How to find an object in an ArrayList by property

JavaArraylistCollections

Java Problem Overview


How can I find an object, Carnet, in a ArrayList<Carnet> knowing its property codeIsin.

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

public class Carnet {

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

    // Setters and getters

}

Java Solutions


Solution 1 - Java

In Java8 you can use streams:

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

Additionally, in case you have many different objects (not only Carnet) or you want to find it by different properties (not only by cideIsin), you could build an utility class, to ecapsulate this logic in it:

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

Solution 2 - Java

You can't without an iteration.

Option 1

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

Option 2

Override the equals() method of Carnet.

Option 3

Storing your List as a Map instead, using codeIsIn as the key:

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

Solution 3 - Java

If you use Java 8 and if it is possible that your search returns null, you could try using the Optional class.

To find a carnet:

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

Solution 4 - Java

Here, We can use a function like this:

To find all the objects with a specific codeIsIn:

  public static List<Item> findBycodeIsin(Collection<Carnet> listCarnet, String codeIsIn) {
            
         return items.stream().filter(item -> codeIsIn.equals(item.getCodeIsIn()))
        .collect(Collectors.toList());
     }

To find a Single item (If the codeIsIn is unique for each object):

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

Solution 5 - Java

Here is a solution using 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
}

Solution 6 - Java

Here is another solution using Guava in Java 8 that returns the matched element if one exists in the list. If more than one elements are matched then the collector throws an IllegalArgumentException. A null is returned if there is no match.

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

Solution 7 - Java

Following with Oleg answer, if you want to find ALL objects in a List filtered by a property, you could do something like:

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

and similarly if you want to filter ALL items in a HashMap with a certain Property

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

Solution 8 - Java

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/

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser1279522View Question on Stackoverflow
Solution 1 - Javaoleg.cherednikView Answer on Stackoverflow
Solution 2 - JavaMennoView Answer on Stackoverflow
Solution 3 - JavaRKrumView Answer on Stackoverflow
Solution 4 - JavaLenzmanView Answer on Stackoverflow
Solution 5 - JavaLinhView Answer on Stackoverflow
Solution 6 - JavasavacView Answer on Stackoverflow
Solution 7 - Javauser1084363View Answer on Stackoverflow
Solution 8 - JavaPrasad KharkarView Answer on Stackoverflow