在Java中比较两个大列表(超过10万)

时间:2019-06-25 06:30:01

标签: java collections java-8 stream java-stream

我想在Java中比较大小不相等的两个大字符串列表更快。我想知道还有什么更好的方法可以提高性能。

我在

中看到性能问题
List<String> list1 = 100k records 
List<String> list2 = 10 million records;

#method1 used removeAll
list1.removeAll(list2);

method2 used java8 streams
List<String> unavailable = list1.stream()
                    .filter(e -> (list2.stream()
                            .filter(d -> d.equals(e))
                            .count())<1)
                            .collect(Collectors.toList());

注意:我试图获取在list1中但在list2中不存在的记录。

2 个答案:

答案 0 :(得分:1)

您唯一可以提高性能的方法是使用 function login (Request $request) : JsonRequest { // code return response()->json($token, 200); } 而不是Set,因为它们的{{1}具有 O(1) }。但是,因此您不应该关心列表中的重复项。

如果您不关心项目的顺序,请使用HashSet,否则请使用LinkedHashSet。使用集几乎没有关系,无论您使用List还是Set.contains(),因为Set.removeAll()在内部使用Stream.filter()

因此,如果您需要一套新的并且不想碰原始的东西,可以选择使用它:

removeAll()

如果您要使用列表作为结果,请使用contains()

Set<String> set2 = new HashSet<>(list2);
Set<String> unavailable = list1.stream()
        .filter(e -> !set2.contains(e))
        .collect(Collectors.toSet());

如果您只想从Collectors.toList()中删除项目,请使用此选项:

Set<String> set2 = new HashSet<>(list2);
List<String> unavailable = list1.stream()
        .filter(e -> !set2.contains(e))
        .collect(Collectors.toList());

或更短:

list1

答案 1 :(得分:0)

List<String> unavailable = list1.stream()
                                .filter(e -> !list2.contains(e))
                                .collect(Collectors.toList());

(或)

List<String> unavailable = list1.stream() 
                                .filter(not(list2::contains)) 
                                .collect(Collectors.toList());

创建如下谓词

public static <T> Predicate<T> not(Predicate<T> t) {
        return t.negate();
    }