consprice
consprice

Reputation: 722

Java - Getting common element from two ArrayLists of different data type

I have two ArrayLists of different size.

ArrayList<String> names = new ArrayList<String>();
ArrayList<User> users = new ArrayList<User>();

User is an Object with attributes name and address. I want to get the addresses where the names of the User object stored in ArrayList users is the same as the names stored in the ArrayList names.

Is this possible? If so, how?

Upvotes: 2

Views: 7429

Answers (5)

ooozguuur
ooozguuur

Reputation: 3476

You can use Java 8.

Please try:

users.stream().filter(u -> names.contains(u.getName())).map(
                u -> "Name: " + u.getName() + ", address: " + u. getAddress()).forEach(System.out::println);

Upvotes: 1

dkb
dkb

Reputation: 4596

In java-8 you can use stream and collectors as below,
Logic is
1. find command attribute in two lists
2. convert a smaller list to Map<Common_attribute, Actual_List_Object>, O(n) complexity
3. iterate the bigger list and check in a map if it contains, and add it in another list, O(n) complexity (map lookup is ~ O(1)) with O(n) space complexity,
else it would be O(n^2) (Accepted answer's complexity)

Assumed user's class as

class User {
        private String name;

        private String getName() {
            return this.name;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    '}';
        }
    }

// code which serves the purpose

import java.util.stream.Collectors;

ArrayList<String> names = new ArrayList<>();
ArrayList<User> users = new ArrayList<>();

//adding to name list
names.add("a");
//adding to User list
User user = new User();
user.name = "a";
User user2 = new User();
user2.name = "b";

users.add(user);
users.add(user2);
// Using user's name as key, you can specify any data type as key and create a map
Map<String, User> nameUserMap = users.stream().collect(Collectors.toMap(user1 -> user1.getName(), user1 -> user1));
System.out.println(nameUserMap);
List<User> filteredList = names
            .stream()
            .map(nameUserMap::get)
            .filter(Objects::nonNull)
            .collect(Collectors.toList());
System.out.println(filteredList);

output:

{a=User{name='a'}, b=User{name='b'}}
[User{name='a'}]

Upvotes: 0

Rob Trickey
Rob Trickey

Reputation: 1311

If you do loop over Users with names.contains(..) inside, you are doing a n^2 loop (approximately speaking).

I would put the users addresses into a map, keyed by name, then loop over the names list, pulling the addresses out of the map. Costs 2n (roughly) instead.

Upvotes: 0

Andrew Logvinov
Andrew Logvinov

Reputation: 21831

for (User u : users) {
  if (names.contains(u.getName()) {
    System.out.println("Name: " + u.getName() + ", address: " + u.getAddress());
  }
}

Upvotes: 7

jayeff
jayeff

Reputation: 148

You need to iterate over the users-list and check for every element if it is contained in names. You might want to use a Set instead of a list for names if you have alot of elements in there.

Upvotes: 0

Related Questions