首页 > 解决方案 > 基于不同和第二个谓词的过滤器列表

问题描述

我的对象如下所示

Store {
   String shopId;
   long distance;
}

我有一个商店列表。

List<Store> storesList = Arrays.asList(
    new Store (1, 1),
    new Store (1, 5),
    new Store (2, 2),
    new Store (1, 1), // this is duplicate
    new Store (1, 2),
    new Store (1, 1), // this is duplicate
    new Store (3, 7)
    new Store (3, 5)
);

输出

Store {shopId=1, distance=1}  // its fine to have any one among 3 duplicates
Store {shopId=2, distance=2}
Store {shopId=3, distance=5}

我可以调用我自己的 distint 方法,如下所示

private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
    Map<Object, Boolean> seen = new ConcurrentHashMap<>();
    return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
}

并像这样过滤它

List<Store> stores= storesList .stream()
        .filter(distinctByKey(pr -> Arrays.asList(pr.getShopId())))
        .collect(toList());

但是如何通过更小的距离同时过滤它呢?

标签: javadata-structuresjava-stream

解决方案


 storesList.stream()
           .collect(Collectors.toMap(
                Store::getShopId,
                Function.identity(),
                BinaryOperator.minBy(Comparator.comparingLong(Store::getDistance))
              ))
           .values()
           .forEach(System.out::println);

您可以合并这些相同Store的 s (by storeId),您会说在合并时您将distance在两个 Store 之间取最小的。


推荐阅读