有两个输入列表如下:
inputA = [
{
name: "A",
age: 20
},
{
name: "B",
age: 30
},
{ name: "C",
age: 25
},
{ name: "D",
age: 28
}
]
inputB = ["D", "B"]
我的首选输出列表必须如下所示:
expectedOutput = [
{
name: "D",
age: 28
},
{
name: "B",
age: 30
},
{ name: "A",
age: 20
},
{ name: "C",
age: 25
}
]
到目前为止我所做的如下所示:
AtomicInteger count = new AtomicInteger();
Collections.sort(inputA, Comparator
.comparing(a ->
if (inputB.indexOf(a.getName()) > -1) {
return -1;
}
else {
return count.incrementAndGet();
})
.thenComparingInt(a -> a.getAge()));
我得到的输出如下
actualOutput = [
{
name: "D",
age: 28
},
{
name: "B",
age: 30
},
{ name: "C",
age: 25
},
{ name: "A",
age: 20
}
]
问题出在列表 inputB
中没有名称的元素。 inputA
中没有原始订单。为了保持原始顺序 { name: "A", age: 20 }
应该在 { name: "C", age: 25 }
之前
如何在使用比较器链接策略时解决这个问题?
更新 排序逻辑是,如果 inputA 具有名称与 inputB 列表相同的对象,则这些元素应位于 inputA 的顶部,然后这些元素必须按其年龄排序,同时保持 inputA 中其他元素的原始顺序inputB 中不存在
这不可能是重复的,因为这个问题试图比较两个列表,并根据第一个列表中对象的属性对公共(public)元素进行排序,同时让其余元素保持原始顺序。
最佳答案
如我所见,如果名称包含在 inputB
中,则需要按年龄对元素进行排序如果 inputB
中没有包含其余元素,则列出并保留它们的原样。列表。按年龄排序的元素应该出现在结果的顶部,而未排序的元素应该出现在结果的底部。
如果这是你需要做的,你可以使用Comparator.comparingInt
并让它返回一个整数,该整数可以是年龄(对于第一种情况)或 Integer.MAX_VALUE
(对于另一种情况)。
你应该优化检查 inputB
,所以它很快。为此,您可以创建一个 HashSet
来自 inputB
.
这是代码:
Set<String> set = new HashSet<>(inputB);
Collections.sort(inputA, Comparator.comparingInt(a -> set.contains(a.getName()) ?
a.getAge() :
Integer.MAX_VALUE));
只要您的年龄不等于 Integer.MAX_VALUE
,这就有效.
这个想法是你总是按年龄比较,但如果一个元素不属于 inputB
,你把年龄变成Integer.MAX_VALUE
.这将产生两个影响:首先,它会使元素不包含在inputB
中。出现在底部;第二,因为你总是返回Integer.MAX_VALUE
, inputA
的顺序列表被保留,因为 Collections.sort
实现稳定排序。
关于java - 使用 Java 比较器按另一个列表对对象列表进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54559933/