Search code examples
javaspringjava-8java-streamcollectors

Get Object from List<Object> if a particular field in Object matches any value from a separate list


I have a list of strings like under which contains all the store Numbers:

List<String> stores = new ArrayList<>; 

And a List of Objects like:

List<UserStores> userStores = new ArrayList<>;

Now, this UserStores class looks something like this:

public class UserStores {
    
    private String storeNo;
    private String storeName;
    private String country;
}

I want to get all the UserStores from this List<UserStores> if any of the storeNo is present in the 'stores' List given above.

For example,

stores = {1,2};
UserStores = [ {2, qwe, wqew}, {1,ABC, India}, {3, asd, USA} ];

expected result = [{1,ABC, India}, {2, qwe, wqew}]; in the order of stores present in 'stores' list,

How can I get this using stream/collectors?

My current code is something like this..can this be improved?

private static List<UserStores> getModifiedUserStoresList(
            List<String> stores, List<UserStores> userStores
    ) {
        List<UserStores> userStoreList = new ArrayList<>();
        
       
        for(int i = 0; i < stores.size(); i++) {
            for(int j = 0; j < userStores.size(); j++) {
                if(userStores.get(j).getStoreNo().equals(stores.get(i))) {
                    userStoreList.add(userStores.get(j));
                    break;
                }
            }
        }
        return userStoreList;
    }

Solution

  • To maintain proper order and keep duplicates, a map Map<String, UserStores> should be created first (e.g. using Collectors.toMap), and then stores should be streamed and mapped by appropriate keys:

    private static List<UserStores> getModifiedUserStoresList(
            List<String> stores, List<UserStores> userStores
    ) {
        Map<String, UserStores> map = userStores.stream()
            .collect(Collectors.toMap(UserStores::getStoreNo, us -> us, (a, b) -> a));
            
        return stores.stream()
            .filter(map::containsKey)
            .map(map::get)
            .collect(Collectors.toList());
    }