user6440081
user6440081

Reputation:

Transforming a List<Object> into a Map<key, List<Object>> using an object's attribute as key

I have an object Foo with the following elements:

class Foo {
    int id;
    int departmentId;
    boolean condition1;
    boolean condition2;
    boolean condition3;
    //...
}

and a list of Foo objects (~10k entries):

List<Foo> fooList = new ArrayList<>();
fooList.add(...);
//...

I need to iterate through each of the departmentIds of this list, and be able to stop any further iterations of a particular departmentId once its objects meet a particular combination of conditions.

For this purpose, I was thinking to simply create a new Map which holds my departmentId as a key and all related Foo objects as its value. So that I could iterate through my new objects based on the departmentId, and easily stop the iteration for other departments with same Id once the condition is met. Something like:

Map<Foo.departmentId, List<Foo>> departmentFoos = new HashMap<>();

Can this be achieved in a better way other than iterating through my fooList and putting/replacing the object of my HashMap one by one?

Upvotes: 0

Views: 155

Answers (2)

Nitika Bansal
Nitika Bansal

Reputation: 749

Using Streams, It can be done this way:

Map<Integer, List<Foo>> output = fooList.stream()
                .collect(Collectors.groupingBy(Foo::getDepartmentId, Collectors.toList()));

Upvotes: 1

dcpomero
dcpomero

Reputation: 999

So in terms of number of iterations, it's unlikely that converting to a Map would give you any benefit, you're better off just going through the list and processing in place. This is required because there's no way to know if you've reached the last appearance of a specific departmentId until you've gone through the entire list of Foos.

So I would do something like:

for (Foo foo : fooList) {
  if (hasBeenProcessed(foo.departmentId) {
    continue;
  }
  process(foo);
}

Note that hasBeenProcessed could be as simple as processedDepartmentIds.contains(foo.departmentId) depending on your needs.

For just converting it to a map, there's nothing that can avoid going through the whole list. There are convenience methods for this in libraries like Guava: Maps.toMap or Guava: Multimaps.index.

Upvotes: 2

Related Questions