有两个输入列表,如下所示:
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中不存在
这不可能重复,因为此问题试图比较两个列表,并且还按照第一个列表中对象的属性对公共元素进行排序,而其余元素保持其原始顺序。
答案 0 :(得分:3)
如我所见,如果名称包含在finished
列表中,则需要按年龄对元素进行排序,如果其余元素不包含在{{1}中,则需要保留其余元素}列表。按年龄排序的元素应显示在结果的顶部,而未排序的元素应显示在结果的底部。
如果这是您需要执行的操作,则可以使用select *
from tbl
where arabic_field <> convert(varchar(8000), arabicfield) --this may be omitted
and arabic-field like '%['+nchar(0x0600)+'-'+nchar(0x06FF)+']%' --checks if contains at least an arabic char (unicode 0600–06FF)
并让它返回一个整数,该整数是age(对于第一种情况)或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
实现了 stable sort 。
答案 1 :(得分:1)
您的代码中的问题是第二个比较器在inputA
中的所有项目上均被激活。这意味着,即使不在inputB
中的项目也将按照inputA
的原始顺序进行排序。您可以这样避免:
Collections.sort(inputA, Comparator.comparing(a ->
{
if (inputB.indexOf(a.getName()) > -1)
{
return 0;
}
return 1;
})
.thenComparingInt(a ->
{
if (inputB.indexOf(a.getName()) > -1)
{
return a.getAge();
}
return Integer.MAX_VALUE;
}));
但是,不确定IndexOf()
是否未排序,是否特别需要两次调用inputB
。也许值得看看生成的字节码以查看是否得到优化。
一件事是,使用计数对比较没有任何影响。您只需在比较操作中返回-1、0或1。因此,对计数进行线程安全增量没有任何价值。
另一方面,如果可以的话,请在用于定义priority
中的对象的类中引入一个inputA
字段。然后,您可以解决多次调用indexOf()
的问题,例如:
Collections.sort(inputA, Comparator.comparing(a ->
{
if (inputB.indexOf(a.getName()) > -1)
{
a.setPriority(a.getAge());
return 0;
}
a.setPriority(Integer.MAX_VALUE);
return 1;
})
.thenComparingInt(a -> a.getPriority()));