Reputation: 722
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
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
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
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
Reputation: 21831
for (User u : users) {
if (names.contains(u.getName()) {
System.out.println("Name: " + u.getName() + ", address: " + u.getAddress());
}
}
Upvotes: 7
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