java 8 如何获得多个属性的不同列表

新手上路,请多包涵

如何从对象列表中获取不同的(基于两个属性的不同)列表。例如,让有属性名称和价格的对象列表。现在如何获得具有不同名称或价格的列表。

认为

list<xyz> l1 = getlist(); // getlist will return the list.

现在让 l1 具有以下属性(名称、价格):-

n1, p1

n1, p2

n2, p1

n2, p3

现在过滤后的列表应该是-

n1, p1

n2, p3

我试过这样解决 -

 public List<xyz> getFilteredList(List<xyz> l1) {

        return l1
                .stream()
                .filter(distinctByKey(xyz::getName))
                .filter(distinctByKey(xyz::getPrice))
                .collect(Collectors.toList());
    }

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

现在的问题是,当我对名称进行过滤时,返回的列表将是 -

n1, p1

n2, p1

然后它会对返回的价格运行过滤器 -

n1, p1

这不是预期的结果。

原文由 rcipher222 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 596
1 个回答

我会选择这样的东西,它相当简单灵活,并以您的示例为基础:

 public static <T> List<T> distinctList(List<T> list, Function<? super T, ?>... keyExtractors) {

    return list
        .stream()
        .filter(distinctByKeys(keyExtractors))
        .collect(Collectors.toList());
}

private static <T> Predicate<T> distinctByKeys(Function<? super T, ?>... keyExtractors) {

    final Map<List<?>, Boolean> seen = new ConcurrentHashMap<>();

    return t -> {

        final List<?> keys = Arrays.stream(keyExtractors)
            .map(ke -> ke.apply(t))
            .collect(Collectors.toList());

        return seen.putIfAbsent(keys, Boolean.TRUE) == null;

    };

}

然后可以通过以下方式调用它:

 final List<Xyz> distinct = distinctList(list, Xyz::getName, Xyz::getPrice)

原文由 lukens 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题