2

I have a list of elements. I want to group the elements of this list into a list of list based on some condition. Is it possible to do it easily in java ?

public class CollectionTest {

    public static void main(String[] arg) {
        Target target0 = new Target();
        target0.setRisklevel("III");
        target0.setLocation("Combined");
        Target target1 = new Target();
        target1.setRisklevel("III");
        target1.setLocation("Combined");
        Target target2 = new Target();
        target2.setRisklevel("III");
        target2.setLocation("Combined");
        Target target3 = new Target();
        target3.setRisklevel("III");
        target3.setLocation("Combined");
        Target target4 = new Target();
        target4.setRisklevel("IV");
        target4.setLocation("Combined");
        Target target5 = new Target();
        target5.setRisklevel("IV");
        target5.setLocation("Combined");
        Target target6 = new Target();
        target6.setRisklevel("IV");
        target6.setLocation("Combined");
        Target target7 = new Target();
        target7.setRisklevel("II");
        target7.setLocation("Domestic");
        Target target8 = new Target();
        target8.setRisklevel("IV");
        target8.setLocation("Domestic");
        Target target9 = new Target();
        target9.setRisklevel("IV");
        target9.setLocation("Domestic");
        Target target10 = new Target();
        target10.setRisklevel("IV");
        target10.setLocation("Domestic");
        Target target11 = new Target();
        target11.setRisklevel("IV");
        target11.setLocation("Domestic");

        List<Target> ucrtargetList = new ArrayList<Target>();
        ucrtargetList.add(target0);
        ucrtargetList.add(target1);
        ucrtargetList.add(target2);
        ucrtargetList.add(target3);
        ucrtargetList.add(target4);
        ucrtargetList.add(target5);
        ucrtargetList.add(target6);
        ucrtargetList.add(target7);
        ucrtargetList.add(target8);
        ucrtargetList.add(target9);
        ucrtargetList.add(target10);
        ucrtargetList.add(target11);
        List<List<Target>> fullList = new ArrayList<List<Target>>();
    }
}

Here condition is RiskLevel and Location has to be same in each list in the list of List. So fullList should have 4 lists within it(1st III & Combined, 2nd IV & Combined, 3rd II & Domestic, 4th IV & Domestic).

I could loop through the list and set the values. Is there an easier way to do this with java8 or apache commons ?

1

3 Answers 3

1

Unable to comment yet, so adding an answer, to extend what @Schidu Luca has replied, 'groupingBy' clauses can be chained, like this

Map<String, List<Target>> collect = ucrtargetList.stream()
           .collect(Collectors.groupingBy(Target::getRisklevel, Collectors.groupingBy(Target::getLocation)));
Sign up to request clarification or add additional context in comments.

2 Comments

Now this returns a key that is RiskLevel and value as hashmaps which again has key as location. Any simple way to get a list of list from this hashmap ?
this is well explained here, in the answer by @Holger [link]stackoverflow.com/questions/38360276/…
1

According to your description fullList should have 4 lists within it(1st III & Combined, 2nd IV & Combined, 3rd II & Domestic, 4th IV & Domestic) I assume your looking for this:

Function<Target, List<String>> riskLevelAndLocation = t -> List.of(t.getRiskLevel(), t.getLocation());
Map<List<String>, List<Target>> fullList = ucrtargetList.stream()
        .collect(Collectors.groupingBy(riskLevelAndLocation));

riskLevelAndLocation is a Function which retruns a List containing riskLevel and location. groupingBy a List works because List.equals(Object o)

Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal.

A quick check:

for (Entry<List<String>, List<Target>> entrySet : fullList.entrySet()) {
    System.out.println(entrySet.getKey().toString() + ": " + entrySet.getValue().size());
}

The output is:

[IV, Combined]: 3
[II, Domestic]: 1
[III, Combined]: 4
[IV, Domestic]: 4

If fullList has to have the order you've described then you could use a LinkedHashMap and sort it.

2 Comments

This works but this seems to be using java10 features. I need solution in java 8 or using external libraries like Apache Commons.
The Java 9 code is List.of. You can use Arrays.asList instead.
0
List<List<Target>> fullList = ucrtargetList.stream()
                .collect(Collectors.groupingBy(Target::getRisklevel)) // Or another collector
                .entrySet()
                .stream()
                .map(Map.Entry::getValue)
                .collect(Collectors.toList());

If you want to remove the same objects from the result, you need to add methods 'equals' and 'hashcode' and collects to Set.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.