Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对对象引用方法Java8使用双冒号_Java_Java 8_Method Reference - Fatal编程技术网

对对象引用方法Java8使用双冒号

对对象引用方法Java8使用双冒号,java,java-8,method-reference,Java,Java 8,Method Reference,我有两个列表,需要通过xxx.getId()将它们相交,所以我使用流和Lambda。这些步骤是: List<xxx> list1 = function1(); List<xxx> list2 = function2(); List<String> list1InString = list1.stream().map(input -> input.getId()).collect(toList()); list2 = list2.stream().filt

我有两个
列表
,需要通过
xxx.getId()
将它们相交,所以我使用
Lambda
。这些步骤是:

List<xxx> list1 = function1();
List<xxx> list2 = function2();
List<String> list1InString = list1.stream().map(input -> input.getId()).collect(toList());
list2 = list2.stream().filter(input -> list1InString.contains(input.getId())).collect(toList());
但这不是真的,因为
包含对xxx对象的引用,而不是字符串getId()方法。我知道我浪费时间将list1转换为list1安装,但我不知道有什么更好的方法。任何帮助都是非常宝贵的,非常感谢。



编辑:谢谢你的回答,我只是想通过使用双冒号使代码更简单(这对我来说是新的),但在这种情况下可能不会使用。特别感谢Naman和Holger非常清楚地说明了我的问题。

您可以使用稍微不同的方法:

List<xxx> list1 = function1();
List<xxx> list2 = function2();
Set<String> seen = new HashSet<>();

List list1=function1();
List list2=function2();
Set seen=新的HashSet();
加入欧盟:

Predicate<xxx> distinctFilter = x -> seen.add(x.getId());
result = Stream.concat(list1.stream(), list2.stream())
.filter(distinctFilter)
.collect(toList());
谓词distinctFilter=x->seen.add(x.getId());
结果=Stream.concat(list1.Stream(),list2.Stream())
.过滤器(distinctFilter)
.collect(toList());
相交:

Predicate<xxx> distinctFilter = x -> !seen.add(x.getId());
result = Stream.concat(list1.stream(), list2.stream())
.filter(distinctFilter)
.collect(toList());
谓词distinctFilter=x->!seen.add(x.getId());
结果=Stream.concat(list1.Stream(),list2.Stream())
.过滤器(distinctFilter)
.collect(toList());

您可以采取以下替代方法:

List<XXX> items = list2.stream()
            .map(itemL1->{
                        return list1.stream().
                            filter((itemL2)->itemL2.getId().equals(itemL1.getId()))
                            .collect(Collectors.toList());
                    }
                )
            .flatMap(List::stream)
            .collect(Collectors.toList());
List items=list2.stream()
.map(项目1->{
返回list1.stream()。
过滤器((itemL2)->itemL2.getId().equals(itemL1.getId())
.collect(Collectors.toList());
}
)
.flatMap(列表::流)
.collect(Collectors.toList());

方法引用的使用只能在
list2
字符串或
map
fiiler
之前的情况下进行,但情况似乎并非如此。@Naman,感谢您的回复。因此,我的步骤是我的案例的可选答案-不能在这个案例中使用双冒号吗?好吧,Ravindra在答案中建议了一种方法,覆盖
equals
,但我个人不建议这样做,因为在一般情况下比较对象时会丢失其他信息。另一种方法是将用于过滤的代码抽象为实用方法,并将其与引用一起使用。但这不应该是必需的,因为lambda已经读得很干净,并且在这里可以正常工作。我建议阅读。它是关于组合两个
函数
实例,但同样适用于组合
谓词
函数
;您可以通过helper函数组合两个方法引用,但最终,只编写lambda表达式没有任何优势。我认为在我的情况下,由于字符串和对象之间的差异,无法调用简单的双冒号。谢谢您的帮助,我将结束我的问题。您可以首先使用
平面图,即
平面图(itemL1->list1.stream().filter(itemL2->itemL2.getId().equals(itemL1.getId())
,而不是先映射到
列表,然后映射到
.flatMap(List::stream)
。但无论如何,这两种方法都不等同于OP的操作,它相当于
list2.stream().filter(a->list1.stream().anyMatch(b->a.getId().equals(b.getId()).collect(Collectors.toList())
。但是最好先将
列表1
的ID收集到集合中,尤其是当使用
集合
而不是
列表
时。谢谢你的回答,但这不是我的要求答案。我需要的是交叉点2列表,而不是并集。我使用lambda的第一步已经完成了。@mmo2112要并集,你只需要n否定谓词。请参阅更新的
List<XXX> items = list2.stream()
            .map(itemL1->{
                        return list1.stream().
                            filter((itemL2)->itemL2.getId().equals(itemL1.getId()))
                            .collect(Collectors.toList());
                    }
                )
            .flatMap(List::stream)
            .collect(Collectors.toList());