Java: collect and combine data in a list

In my program, I have a list of plants, each plant has a dimension (String), day (int), camera (int) and replication number (int). I get a list of all the plants that are needed with filters:

List<Plant> selectPlants = allPlants.stream().filter(plant -> passesFilters(plant, filters)).collect(Collectors.toList());

What I would like to do now is to take all Plants that have the same values ​​for camera, measurement, and replication. And combine them in the order of the day. Therefore, if I have days 1,2,3,5, I would like to find all similar plants and add values ​​to one plant, where getValues ​​(function).

I added a Plant method that adds values ​​simply using addAll (new values ​​to set).

Is there a way to do this without repeating through the list many times to find similar plants and then sort them every day and then add? I apologize for the awful wording of this question.

+4
source share
4 answers

While Wachs answer is correct, it is unnecessarily complex.

Often, the work of implementing your own key class does not pay off. You can use it Listas a key, which implies a small overhead due to primitive values ​​of the box, but given the fact that we perform operations such as hashing, this will be insignificant.

, for , , Comparator. ? Comparator , (p1,p2) -> p1.getDay()-p2.getDay() , , Comparator.comparing(Plant::getDay).

, . sort , , :

Map<List<?>, List<Plant>> groupedPlants =  allPlants.stream()
  .filter(plant -> passesFilters(plant, filters))
  .sorted(Comparator.comparing(Plant::getDay))
  .collect(Collectors.groupingBy(p ->
     Arrays.asList(p.getMeasurement(), p.getCamera(), p.getReplicateNumber())));

.

+7

Collectors.groupBy:

private static class PlantKey {
    private String measurement;
    private int camera;
    private int replicateNumber;
    // + constructor, getters, setters and haschode equals
}

Map<PlantKey, List<Plant>> groupedPlants = 
  allPlants.stream().filter(plant -> passesFilters(plant, filters))
                    .collect(Collectors.groupBy(p -> 
                               new PlantKey(p.getMeasurement(),
                                            p.getCamera(),
                                            p.getReplicateNumber())));

// order the list
for(List values : groupedPlants.values()) {
    Collections.sort(values, new Comparator<Plant>(){
                       @Override
                       public int compare(Plant p1, Plant p2) {
                           return p1.getDay() - p2.getDay();
                       }
                     });
}
+4

.

for(List<Plant> plantGroup : allPlants.stream().collect(Collectors.groupingBy(
                p -> p.camera+'/'+p.measurement+'/'+p.replicate)).values()) {
    // compare the plants in the same group
}
+1

sorted, stream

selectPlants.stream().sorted(Comparator.comparingInt(i -> i.day)).collect(Collectors.toList());
+1

Source: https://habr.com/ru/post/1545898/


All Articles