根据另一个列表排序列表 Java
Order a list based on another list Java
我有两个列表 list1
和 list2
,如下所示
列表 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
需要 equals
和 hashCode
,这样 list::contains
才能工作。
首先找出list1中所有不在list2中的元素。
list3 = list1.stream()
.filter(Predicate.not(list2::contains))
.collect(Collectors.toList());
那么,如果
- list2 中没有属于
list1
的 NOT 部分的元素。在这种情况下,只需简单地将 list2 的所有元素添加到 list1
list3.addAll(list2);
- 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());
});
我有两个列表 list1
和 list2
,如下所示
列表 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
需要 equals
和 hashCode
,这样 list::contains
才能工作。
首先找出list1中所有不在list2中的元素。
list3 = list1.stream()
.filter(Predicate.not(list2::contains))
.collect(Collectors.toList());
那么,如果
- list2 中没有属于
list1
的 NOT 部分的元素。在这种情况下,只需简单地将 list2 的所有元素添加到 list1
list3.addAll(list2);
- 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());
});