切换到Java 8时的比较器问题
我正在从Java6迁移到Java8,并注意到Comparator接口的一些特殊之处。对此的任何见解都将非常有用 当我切换到Java8时,对象的顺序在“compare”方法中被切换,列表排序失败。我回到Java6,它工作得很好。这里有一个测试用例,我用Java8失败,用Java6通过切换到Java 8时的比较器问题,java,sorting,java-8,comparator,java-6,Java,Sorting,Java 8,Comparator,Java 6,我正在从Java6迁移到Java8,并注意到Comparator接口的一些特殊之处。对此的任何见解都将非常有用 当我切换到Java8时,对象的顺序在“compare”方法中被切换,列表排序失败。我回到Java6,它工作得很好。这里有一个测试用例,我用Java8失败,用Java6通过 public class ComparitorTest { @Test public void comparatorTest(){ Record record1 = new Record("First",
public class ComparitorTest {
@Test
public void comparatorTest(){
Record record1 = new Record("First", false);
Record record2 = new Record("Second", true);
List<Record> list = new ArrayList<Record>();
list.add(record1);
list.add(record2);
final Comparator<Object> recordComparator = new Comparator<Object>()
{
public int compare( Object o1, Object o2 )
{
Record r1 = (Record) o1;
Record r2 = (Record) o2;
Boolean isReadonly_R1 = r1.getIsReadOnly();
Boolean isReadOnly_R2 = r2.getIsReadOnly();
if( isReadonly_R1.equals( Boolean.TRUE ) )
{
return 0;
}
else
{
return 1;
}
}
};
Collections.sort(list, recordComparator);
assertEquals(list.get(0).name, "Second");
assertEquals(list.get(1).name, "First");
}
class Record {
boolean isReadOnly;
String name;
public Record(String name, boolean value) {
isReadOnly =value;
this.name = name;
}
boolean getIsReadOnly() {
return isReadOnly;
}
}
公共类比较测试{
@试验
public void comparatorTest(){
记录1=新记录(“第一条”,假);
记录2=新记录(“第二条”,真);
列表=新的ArrayList();
列表。添加(记录1);
列表。添加(记录2);
最终比较器记录比较器=新比较器()
{
公共整数比较(对象o1、对象o2)
{
记录r1=(记录)o1;
记录r2=(记录)o2;
布尔值isReadonly_R1=R1.getIsReadOnly();
布尔值isReadOnly_R2=R2.getIsReadOnly();
if(isReadonly_R1.equals(Boolean.TRUE))
{
返回0;
}
其他的
{
返回1;
}
}
};
集合。排序(列表、记录比较器);
assertEquals(list.get(0).name,“Second”);
assertEquals(list.get(1.name),“First”);
}
课堂记录{
布尔值为只读;
字符串名;
公共记录(字符串名称,布尔值){
isReadOnly=值;
this.name=名称;
}
布尔getIsReadOnly(){
返回为只读;
}
}
}
你们在这方面的任何见解都会非常有帮助你们的比较仪完全崩溃了。如果说到目前为止一切顺利的话,那完全是因为运气 如果您确实比较(a,b)和
比较(b,a)
,则
和a
相等,两个调用都返回0b
和a
不相等,一个呼叫返回正数,另一个呼叫返回负数b
compare
合同。您没有设置订单关系
另一个赠品提示是,您仅使用r1计算结果…您的
比较器
不是有效的比较器。它只查看要比较的第一项;它忽略了第二项。它不能返回负数,这意味着第一项不能被视为“小于”第二项
用于对列表进行排序的算法碰巧在Java6中工作(毕竟它有50/50的机会),但该算法必须在Java6和Java8之间进行更改
您需要根据以下内容修复比较器的逻辑:
比较其两个参数的顺序。返回负整数、零或正整数,因为第一个参数小于、等于或大于第二个参数
此外,它不需要是比较器。使它成为一个比较器
,比较
方法可以使用记录
s而不是对象
s。补充现有答案,我将在Java 8中添加以下内容,您应该放弃整个自定义比较器实现。显然,您希望对记录进行排序,以便所有只读记录排在第一位,然后是所有可写记录。这是Java 8中的一行程序:
list.sort(Comparator.comparing(Record::getIsReadOnly).reverseOrder());
是的,算法改变了。在Java7中引入了TimSort。还有一个允许恢复到旧算法的系统属性,但由于修复损坏的比较器应该是首选,我不会浪费时间查找该属性的确切名称…