Java 从列表中删除重复项:旧方法与流设计思想?

Java 从列表中删除重复项:旧方法与流设计思想?,java,optimization,collections,functional-programming,Java,Optimization,Collections,Functional Programming,只是一个从字符串列表中删除重复项的示例探索。旧方法在执行方面优于新的lambda/stream方法。新方法背后的设计思想是什么?与性能相比,它还有其他好处吗 List<String> nameList = new ArrayList<>(); Collections.addAll(nameList, "Raj","Nil",.......); removeDupViaSet(nameList); removeDupViaStream(nameList); private

只是一个从字符串列表中删除重复项的示例探索。旧方法在执行方面优于新的lambda/stream方法。新方法背后的设计思想是什么?与性能相比,它还有其他好处吗

List<String> nameList = new ArrayList<>();
Collections.addAll(nameList, "Raj","Nil",.......);
removeDupViaSet(nameList);
removeDupViaStream(nameList);

private static void removeDupViaStream(List<String> nameList) {
    long start = System.nanoTime();
    List<String> nm = nameList.stream().distinct().collect(Collectors.toList());
    long end = System.nanoTime() - start;
    System.out.println("Dup Removed via Stream : " + end);
}


private static void removeDupViaSet(List<String> nameList) {
    long start = System.nanoTime();
    Set<String> tempHashSet = new HashSet<>();
    tempHashSet.addAll(nameList);
    nameList.clear();
    nameList.addAll(tempHashSet);
    long end = System.nanoTime() - start;
    System.out.println("Dup Removed via Set : " + end);
}
List nameList=new ArrayList();
集合。添加所有(名称列表,“Raj”、“Nil”和……);
移除过孔集(名称列表);
移除的高架桥(名称列表);
私有静态void removeDupViaStream(列表名称列表){
长启动=System.nanoTime();
List nm=nameList.stream().distinct().collect(Collectors.toList());
long end=System.nanoTime()-开始;
System.out.println(“通过流删除Dup:“+end”);
}
私有静态void removeDupViaSet(列表名称列表){
长启动=System.nanoTime();
Set tempHashSet=新HashSet();
tempHashSet.addAll(名称列表);
nameList.clear();
nameList.addAll(tempHashSet);
long end=System.nanoTime()-开始;
System.out.println(“通过Set删除Dup:”+结束);
}
通过Set:1186909删除Dup

通过流删除Dup:67513136

合同内容如下:

返回由此流的不同元素(根据Object.equals(Object))组成的流


因此,由于它只能使用
equals
,因此不能使用
hashcode
,所以您正在比较苹果和桔子。任何允许使用
hashcode
(例如
HashSet
)的算法都肯定会优于
distinct

,一般来说,使用流时不会一直获得性能。这取决于操作和数据大小,例如,与旧式方法相比,大小为10的列表中的并行流将不会有效。如果10公里的话,它的表现将远远超过尺寸


最好在评估性能时考虑操作和数据大小。

LAMBDAS让你做同样的事情,通常用更少的代码行。如果你想避免冗长的前Java 8代码模式,这就是使用它们的一个原因。你不能这样衡量性能-流版本可能会因为流开销而稍微慢一点,但我怀疑它会慢70倍。请参阅:这不是对运行时差异的解释,但您知道set方法可能会扰乱列表中元素的顺序,对吗?不过,使用LinkedHashSet可能会有所帮助。我只是在一个测试类中尝试了这一点,每次调用hashcode或equals时,都会增加一些计数器,在这两种情况下,它们都会被调用,而且调用频率大致相同(使用stream,hashcode甚至会被调用得更频繁一些,但这还不足以解释差异)任何允许使用
equals
的东西也可以使用
hashCode
,否则就没有意义了。。。我在医生的任何地方都看不到这一点,但我毫不犹豫。