Java-Stream-API: сокращение карты - PullRequest
0 голосов
/ 20 декабря 2018

Допустим, у меня есть несколько java-объектов типа obj_vx с разными датами и временем (в качестве переменной-члена).

obj_v1[D1]
obj_v1[D2]
obj_v1[D3]
obj_v1[D4]

obj_v2[D2]
obj_v2[D3]
obj_v2[D4]

obj_v3[D2]
obj_v3[D3]
obj_v3[D4]

obj_v4[D1]
obj_v4[D2]
obj_v4[D5]


obj_v5[D1]
obj_v5[D4]
obj_v5[D5]
obj_v5[D6]

obj_v5[D4]
obj_v5[D5]

or 

obj_v1 [D1, D2, D3, D4]
obj_v2 [D2, D3, D4]
obj_v3 [D2, D3, D4]
obj_v4 [D1, D2, D5]
obj_v5 [D1, D4, D5, D6]
obj_v6 [D4, D5]

Теперь я хочу выполнить фильтрацию по заданномудата D (с D1 obj_vx с самой младшей датой (D2 моложе D1) , который все еще старше (или равен)чем D. Может кто-нибудь сказать мне, как построить его с Java-Stream-API?

Операция Map-Reduce возвращает список obj_vx объектов.

Ответ:

- after 1st iteration
obj_v1 [D1, D2, D3]
obj_v2 [D2, D3]
obj_v3 [D2, D3]
obj_v4 [D1, D2]
obj_v5 [D1]
- after 2nd iteration
obj_v1[D3], obj_v2[D3], obj_v3[D3], obj_v4[D2], obj_v5[D1].

Предложение:

public class FilterTest {
       static class X {
             String group;
             int y;

             X(String group, int y) {
                    this.group = group;
                    this.y = y;
             }

             public String getGroup() {
                    return group;
             }

             public int getY() {
                    return y;
             }

             @Override
             public String toString() {
                    return String.format("[group: '%s', y: '%s']", group, y);
             }
       }

       public static void main(String[] args) {
             int val = 2;

             List<X> l = new ArrayList<>();
             l.add(new X("A", 1));
             l.add(new X("Y", 3));
             l.add(new X("A", 2));
             l.add(new X("Y", 1));
             l.add(new X("B", 8));
             l.add(new X("A", 3));

             Map<String, X> map = l.stream().filter(d -> d.y <= val).collect(
                     Collectors.groupingBy(X::getGroup,
                         Collectors.collectingAndThen(
                             Collectors.reducing(
                                        (X d1, X d2) -> d1.getY() > d2.getY() ? d1 : d2
                           ),
                             Optional::get)));
             System.out.println("m: " + map);     
       }
}

1 Ответ

0 голосов
/ 20 декабря 2018

Лучший способ представить ваше предложение может быть:

Map<String, X> map = l.stream()
        .filter(d -> d.getY() <= val)
        .collect(Collectors.toMap(X::getGroup, Function.identity(), 
                BinaryOperator.maxBy(Comparator.comparing(X::getY))));
...