0

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?

asked Jun 17, 2019 at 1:12
8
  • 3
    By Set, do you actually mean Map? Commented Jun 17, 2019 at 1:13
  • 2
    OP doesn't say that there are other departments with the same ID, just that there are other Foo's with the same departmentId, which sounds reasonable enough. Commented Jun 17, 2019 at 1:25
  • 1
    @jas Yes he does. You assume the "departments" from the quote is meant to be "Foo", and it is reasonable to assume that, but that's not what OP wrote. Commented Jun 17, 2019 at 1:31
  • 1
    Quite true, @Tom, I see your point. I was assuming without even realising it. Agree that it's good to clarify these things. Commented Jun 17, 2019 at 1:36
  • 1
    @CoffeeCups You can formulate the Map that you are looking for using Collectors.groupingBy while streaming the initial List<Foo>. After which, you can iterate over the (key, val) pairs and iterate further on the val to find anyMatch and break further traversal. Commented Jun 17, 2019 at 4:59

2 Answers 2

2

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.

answered Jun 17, 2019 at 1:26

Comments

1

Using Streams, It can be done this way:

Map<Integer, List<Foo>> output = fooList.stream()
 .collect(Collectors.groupingBy(Foo::getDepartmentId, Collectors.toList()));
answered Jun 17, 2019 at 5:56

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.