根据另一个列表排序列表 Java

Order a list based on another list Java

我有两个列表 list1list2,如下所示

列表 1 列表 2
{"EmpName":"Tony","EmpId":123} {"EmpName":"David","EmpId":123}
{"EmpName":"Mark","EmpId":123} {"EmpName":"Steve","EmpId":123}
{"EmpName":"Steve","EmpId":123} {"EmpName":"Mark","EmpId":123}
{"EmpName":"David","EmpId":123}
{"EmpName":"John","EmpId":123}
{"EmpName":"Jim","EmpId":123}

现在我想根据 list2 对 list1 进行排序。

如果 list1 中的元素不在 list2 中,则元素位于顶部,如果元素存在于 list2 中,则其顺序应与 [=13] 相同=].

所以我希望结果 table 是这样的。

结果列表
{"EmpName":"Tony","EmpId":123}
{"EmpName":"John","EmpId":123}
{"EmpName":"Jim","EmpId":123}
{"EmpName":"David","EmpId":123}
{"EmpName":"Steve","EmpId":123}
{"EmpName":"Mark","EmpId":123}

我有以下代码可以执行此操作,并且可以正常工作。我真的不确定这是否会在某些情况下中断,或者是否有更好的方法来实现这一点:

List<Employee> list = new ArrayList<>();
list.add(new Employee("Tony",123));
list.add(new Employee("Mark",123));
list.add(new Employee("Steve",123));
list.add(new Employee("David",123));
list.add(new Employee("John",123));
list.add(new Employee("Jim",123));

List<Person> list2 = new ArrayList<>();
list2.add(new Employee("David",123));
list2.add(new Employee("Steve",123));
list2.add(new Employee("Mark",123));

List<Person> newList = new ArrayList<>();
list2.forEach(e->{
        if(list.stream().filter(doc->e.getName().equalsIgnoreCase(doc.getName())).findAny().isPresent()){
                newList.add(e);
                list.removeIf(i->i.getName().equalsIgnoreCase(e.getName()));
            }
        });
        list.addAll(newList);
        System.out.println(list);

    }

注意:Employee 需要 equalshashCode,这样 list::contains 才能工作。

首先找出list1中所有不在list2中的元素。

list3 = list1.stream()
             .filter(Predicate.not(list2::contains))
             .collect(Collectors.toList());

那么,如果

  1. list2 中没有属于 list1NOT 部分的元素。在这种情况下,只需简单地将 list2 的所有元素添加到 list1
list3.addAll(list2);
  1. list2 中有 may/may 不在 list1 中的元素。将 list2 中 list1 中的元素添加到 list3。
list3.addAll(list2.stream().filter(list1::contains).collect(Collectors.toList()));

我只使用带有每个名称索引的映射,以简化查找:

Map<String, Integer> indexOfMap = IntStream.range(0, list2.size())
        .mapToObj(i -> Map.entry(list2.get(i).getName(), i))
        .collect(Collectors.toMap(Entry::getKey, Entry::getValue));

然后实现一个 Comparator,通过在 indexOfMap 中查找名称进行排序:

Comparator<Employee> comparator = (a, b) -> 
   indexOfMap.containsKey(a.getName()) && indexOfMap.containsKey(b.getName())
        ? indexOfMap.get(a.getName()) - indexOfMap.get(b.getName())
        : (!indexOfMap.containsKey(a.getName()) ? -1 : 1);

//you can make a copy of list if you don't want to change it
//or you can stick to your stream and just use sorted with the comparator
list.sort(comparator);

请注意,结果列表中第一个元素的顺序是不确定的(因为它只是 list2 中不存在的所有元素,没有进一步的排序)。列表末尾的所有值将按照 list2.

规定的顺序排列

您不需要创建新列表。看下面的代码这是简单的两步过程

 list2.stream().forEach((e)->list.removeIf(employee->employee.getName().equalsIgnoreCase(e.getName())));
        
        list.addAll(list2);

list.stream().forEach((employee)->{
            System.out.println(employee.getName());
        });