提问人:Darkwriter 提问时间:6/10/2022 最后编辑:WJSDarkwriter 更新时间:6/11/2022 访问量:1331
JAVA 8 distinctByKey
JAVA 8 distinctByKey
问:
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;
}
谁能帮帮我,
这句话是什么意思------->
return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
为什么 lambda 结果与 null 结果相比?
答:
1赞
WJS
6/10/2022
#1
您的问题围绕以下内容展开:
return t -> seen.putIfAbsent(keyExtractor.apply(t),
Boolean.TRUE) == null;
- 首先,返回整个 lambda(从 t->..开始)。它仍然将创建的地图引用为通路,即使地图本身现在超出了范围。
closure
seen
- 将通过作为方法引用提供的 setter (
keyExtractor
e.g. XYZ::getName
) putIfAbsent
尝试将布尔值添加到所提供键的映射中(在本例中为 和 from )。如果键已存在,则返回该值,该值为 。由于不等于 ,因此返回,并且筛选器不传递该值。如果该值不存在,则返回 null。由于为 true,因此将返回并通过过滤器传递的值(即到目前为止它是不同的)。true
name
price
keyExtractor
true
true
null
false
null == null
true
下面是其工作原理的示例。这使用简单的记录,并且仅对名称应用筛选器。
record XYZ(String getName, String other){
@Override
public String toString() {
return String.format("[name=%s, other=%s]", getName, other);
}
}
public static void main(String[] args) {
List<XYZ> l1 = List.of(
new XYZ("A","B"),
new XYZ("B","B"),
new XYZ("B","C"),
new XYZ("B","D"),
new XYZ("C","B"));
Object ob =
l1.stream().filter(distinctByKey(XYZ::getName))
.collect(Collectors.toList());
System.out.println(ob);
}
指纹
[[name=A, other=B], [name=B, other=B], [name=C, other=B]]
请注意,只有第一个 Name of 被允许通过过滤器,其他名称都被阻止了。B
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;
}
评论
0赞
BSL
9/11/2022
谢谢你@WJS有用的解释。你能给我一个关于如何对这个函数进行单元测试的想法吗(distinctByKey())?另外,为什么我们在谓词<T>之前有<T>?谢谢。
0赞
WJS
9/11/2022
第二个问题最好在 Java 教程的泛型方法一节中回答。就 Junit 测试而言,一种方法是进行过滤预定义数据结构(例如 )并返回内容的测试。然后,这些内容将与另一个预期结果进行比较,并返回 true 或 false。list
list
0赞
BSL
9/11/2022
非常感谢@WJS的宝贵回答!
评论