gpt4 book ai didi

java - 有效地比较 2 个列表以替换和排序

转载 作者:搜寻专家 更新时间:2023-11-01 02:19:13 24 4
gpt4 key购买 nike

我有 2 个包含一些对象(水果类)的列表。我正在使用第三个列表根据以下两个标准添加这些元素。

我希望第一个列表中的每个对象都添加到第三个列表中。但是如果我在第二个列表中有一个匹配的对象(基于 id 和 isChecked 匹配),我想将第二个列表中的对象添加到第三个列表并忽略第一个列表中的对象。

如果我做了第一点提到的切换,我想将该对象向上移动到第三个列表的第一个元素。

我让它与以下代码一起工作。但是我觉得效率很低。有更好的解决方法吗?

请记住,我无法控制第二个列表,但第一个列表来自 Rest 端点,我目前正在将其捕获为列表。不确定我是否应该选择 map 。请指教。

例子:

在下面的示例中,预期的列表输出是 [f2, f5, f1, f3, f4](基于名称)。

这是因为我拥有第一个列表中的所有元素。 f2 和 f5 排在顺序前面,因为它们来自第二个列表(它们匹配第一个列表中的元素并将 isChecked 设置为 true)。

import lombok.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class App {
public static void main(String[] args) {

Fruit fruit1 = new Fruit("1", "f1", false);
Fruit fruit2 = new Fruit("2", "f2", false);
Fruit fruit3 = new Fruit("3", "f3", false);
Fruit fruit4 = new Fruit("4", "f4", false);
Fruit fruit5 = new Fruit("5", "f5", false);

List<Fruit> firstList = Arrays.asList(fruit1, fruit2, fruit3, fruit4, fruit5);

Fruit fruit6 = new Fruit("2", "f2", true);
Fruit fruit7 = new Fruit("7", "f7", false);
Fruit fruit8 = new Fruit("5", "f5", true);
Fruit fruit9 = new Fruit("9", "f9", false);
Fruit fruit10 = new Fruit("10", "f10", false);

List<Fruit> secondList = Arrays.asList(fruit6, fruit7, fruit8, fruit9, fruit10);

List<Fruit> finalList = new ArrayList<>();

// expected list = [f2, f5, f1, f3, f4]

// this loop is checking and adding objects to finalList.
// must match the first list and isChecked.
// in this case, only f6 and f8 matches the first list (id match) and is also 'checked'.
for (Fruit first : firstList){
for (Fruit second : secondList){
if(first.getId().equals(second.getId()) && second.isChecked()){
finalList.add(second);
break;
}
}
}

// not done yet. Still need to loop and add back the elements from the first list
// which were not added in the above loop
boolean addedFirst = false;
outer:
for(Fruit first : firstList){
for(Fruit finalFruit : finalList){
if(first.getId().equals(finalFruit.getId())){
continue outer;
}
}
finalList.add(first);
}

for(Fruit fruit : finalList){
System.out.println(fruit);
}
}
}

@Getter
@Setter
@ToString
class Fruit{
private String id;
private String name;
private boolean isChecked;

Fruit(String id, String name, boolean isChecked) {
this.id = id;
this.name = name;
this.isChecked = isChecked;
}
}

最佳答案

我的建议是覆盖 Object#equals(java.lang.Object)对于Fruit类。

@Override
public boolean equals(Object obj) {
if (!(obj instanceof Fruit))
return false;
return id.equals(((Fruit)obj).getId());
}

. . .

for (Fruit fruit : firstList) {
if (secondList.contains(fruit)) {
int index = secondList.indexOf(fruit);
fruit = secondList.get(index);
}
finalList.add(fruit);
}

为了保持所需的排序顺序 - 首先列出第二个元素,然后是第二个中不匹配的元素 - 可以这样做:

List<Fruit> finalList = new ArrayList<>(secondList);
finalList.retainAll(firstList);
for (Fruit fruit : firstList) {
if (!finalList.contains(fruit))
finalList.add(fruit);
}

finalList 顺序现在是 [f2, f5, f1, f3, f4]

由于 equals 方法覆盖,这再次起作用。

参见 java.util.List.retainAll() .

这些方法中的每一种都为每个循环和搜索操作使用线性 O(n) 计算时间 - 例如 indexOfretainAll


与主题相关,我认为你想要实现的目标不是很清楚:

f2 and f5 went in front of the order as they came from second list (they matched elements in first list and had isChecked set to true)

如果第一个列表中的 isChecked 设置为 false 会发生什么?第二个列表中的元素是否始终排在第一位并且保留 isChecked 顺序,所以基本上您希望在同一个结果列表中进行两种不同类型的排序?

关于java - 有效地比较 2 个列表以替换和排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54251146/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com