如何通过属性查找数组列表中的对象

我怎样才能找到一个对象,Carnet,在一个 ArrayList<Carnet>知道它的属性 codeIsin

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


public class Carnet {


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


// Setters and getters


}
256621 次浏览

你不能没有一个迭代。

选择一

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

选择二

重写 Carnetequals()方法。

选择三

List存储为 Map,使用 codeIsIn作为键:

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

For finding objects which are meaningfully equal, you need to override equals and hashcode methods for the class. You can find a good tutorial here.

Http://www.thejavageek.com/2013/06/28/significance-of-equals-and-hashcode/

下面是使用 Guava的解决方案

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
}

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()));
}
}

如果使用 爪哇8,并且搜索可能返回 null,则可以尝试使用 可以选择类。

找到一张通行证:

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();
}

Now a usage for it:

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();
}
}

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

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

接下来是 Oleg 的回答,如果您希望在通过属性过滤的 List中找到 全部对象,您可以执行以下操作:

//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中的 ALL

//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()));
}
}

To find an object in an ArrayList by the property, We can use a function like this:

查找具有特定 codeIsIn 的所有对象:

  public static List<Item> findBycodeIsin(Collection<Carnet> listCarnet, String codeIsIn) {
            

return items.stream().filter(item -> codeIsIn.equals(item.getCodeIsIn()))
.collect(Collectors.toList());
}

要查找 Single item (如果 codeIsIn 对每个对象都是唯一的) :

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