如何通过属性在ArrayList中查找对象


78

CarnetArrayList<Carnet>知道对象的属性的情况下,我该如何找到它codeIsin

List<Carnet> listCarnet = carnetEJB.findAll();

public class Carnet {

    private String codeTitre;
    private String nomTitre;
    private String codeIsin;

    // Setters and getters

}

3
使用indexOf(),前提是您的对象被覆盖equals()
jlordo

Carnet类在jar文件中,我无法覆盖equals()

1
如果我是你,我将从任何地方找到源代码,并使其等于equals并实现hashCode。唯一的其他选择是手动遍历Collection并检查成员是否相等。
蒂哈拉2013年

我宁愿使用地图而不是列表。如果您经常寻找对象并且性能是一个问题,那么排序的映射可能会更好。在我看来,为此目的实现和使用均等是丑陋的。
mmirwaldt

2
对于Java 8,您可以从ArrayList中获取流,并对其应用filter(e-> e.codeIsIn.equals(...))。
托尔比约恩Ravn的安徒生

Answers:


77

您不能没有迭代。

选项1

Carnet findCarnet(String codeIsIn) {
    for(Carnet carnet : listCarnet) {
        if(carnet.getCodeIsIn().equals(codeIsIn)) {
            return carnet;
        }
    }
    return null;
}

选项2

覆盖的equals()方法Carnet

选项3

而是将您的存储List为密钥:MapcodeIsIn

HashMap<String, Carnet> carnets = new HashMap<>();
// setting map
Carnet carnet = carnets.get(codeIsIn);

8
我没有Option2。我优先equals(),然后做什么?
idclev 463035818 '18

@ idclev463035818我猜想使用该ArrayList.indexOf方法
Moosefeather

71

Java8中,您可以使用流:

public static Carnet findByCodeIsIn(Collection<Carnet> listCarnet, String codeIsIn) {
    return listCarnet.stream().filter(carnet -> codeIsIn.equals(carnet.getCodeIsin())).findFirst().orElse(null);
}

另外,如果您有许多不同的对象(不仅是Carnet),或者想通过不同的属性(不仅是通过cideIsin)找到它,则可以构建一个实用程序类,以将其逻辑封装在其中:

public final class FindUtils {
    public static <T> T findByProperty(Collection<T> col, Predicate<T> filter) {
        return col.stream().filter(filter).findFirst().orElse(null);
    }
}

public final class CarnetUtils {
    public static Carnet findByCodeTitre(Collection<Carnet> listCarnet, String codeTitre) {
        return FindUtils.findByProperty(listCarnet, carnet -> codeTitre.equals(carnet.getCodeTitre()));
    }

    public static Carnet findByNomTitre(Collection<Carnet> listCarnet, String nomTitre) {
        return FindUtils.findByProperty(listCarnet, carnet -> nomTitre.equals(carnet.getNomTitre()));
    }

    public static Carnet findByCodeIsIn(Collection<Carnet> listCarnet, String codeIsin) {
        return FindUtils.findByProperty(listCarnet, carnet -> codeIsin.equals(carnet.getCodeIsin()));
    }
}

2

这是使用番石榴的解决方案

private User findUserByName(List<User> userList, final String name) {
    Optional<User> userOptional =
            FluentIterable.from(userList).firstMatch(new Predicate<User>() {
                @Override
                public boolean apply(@Nullable User input) {
                    return input.getName().equals(name);
                }
            });
    return userOptional.isPresent() ? userOptional.get() : null; // return user if found otherwise return null if user name don't exist in user list
}

2

下面是使用另一种解决方案番石榴的Java 8如果在列表中存在返回匹配的元素。如果匹配多个元素,则收集器将抛出IllegalArgumentException。一,如果没有匹配,返回。

Carnet carnet = listCarnet.stream()
                    .filter(c -> c.getCodeIsin().equals(wantedCodeIsin))
                    .collect(MoreCollectors.toOptional())
                    .orElse(null);

1

如果使用Java 8,并且搜索有可能返回null,则可以尝试使用 Optional类。

要查找证章:

private final Optional<Carnet> findCarnet(Collection<Carnet> yourList, String codeIsin){
    // This stream will simply return any carnet that matches the filter. It will be wrapped in a Optional object.
    // If no carnets are matched, an "Optional.empty" item will be returned
    return yourList.stream().filter(c -> c.getCodeIsin().equals(codeIsin)).findAny();
}

现在,它的用法是:

public void yourMethod(String codeIsin){
    List<Carnet> listCarnet = carnetEJB.findAll();

    Optional<Carnet> carnetFound = findCarnet(listCarnet, codeIsin);

    if(carnetFound.isPresent()){
        // You use this ".get()" method to actually get your carnet from the Optional object
        doSomething(carnetFound.get());
    }
    else{
        doSomethingElse();
    }
}

0

按照Oleg的回答,如果要在按属性筛选的列表中查找所有对象,可以执行以下操作:

//Search into a generic list ALL items with a generic property
public final class SearchTools {
       public static <T> List<T> findByProperty(Collection<T> col, Predicate<T> filter) {
           List<T> filteredList = (List<T>) col.stream().filter(filter).collect(Collectors.toList());
           return filteredList;
     }

//Search in the list "listItems" ALL items of type "Item" with the specific property "iD_item=itemID"
public static final class ItemTools {
         public static List<Item> findByItemID(Collection<Item> listItems, String itemID) {
             return SearchTools.findByProperty(listItems, item -> itemID.equals(item.getiD_Item()));
         }
     }
}

同样,如果您想过滤具有特定属性的HashMap中的所有项目

//Search into a MAP ALL items with a given property
public final class SearchTools {
       public static <T> HashMap<String,T> filterByProperty(HashMap<String,T> completeMap, Predicate<? super Map.Entry<String,T>> filter) {
           HashMap<String,T> filteredList = (HashMap<String,T>) completeMap.entrySet().stream()
                                .filter(filter)
                                .collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));
           return filteredList;
     }

     //Search into the MAP ALL items with specific properties
public static final class ItemTools {

        public static HashMap<String,Item> filterByParentID(HashMap<String,Item> mapItems, String parentID) {
            return SearchTools.filterByProperty(mapItems, mapItem -> parentID.equals(mapItem.getValue().getiD_Parent()));
        }

        public static HashMap<String,Item> filterBySciName(HashMap<String,Item> mapItems, String sciName) {
            return SearchTools.filterByProperty(mapItems, mapItem -> sciName.equals(mapItem.getValue().getSciName()));
        }
    }

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.