切换到Java 8时的比较器问题

use*_*108 0 java sorting comparator java-6 java-8

我正在从Java 6迁移到Java 8,并注意到Comparator接口特有的一些东西.对此的任何见解都会非常有帮助.

当我切换到Java 8时,对象的顺序在"compare"方法内切换,列表排序失败.我回到java 6,它工作得很好.这是一个测试用例,使用Java 8失败了,并且使用了Java 6.

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;
    }
}   
Run Code Online (Sandbox Code Playgroud)

}

你们对此有任何见解会非常有帮助

rge*_*man 10

Comparator不是有效的Comparator.它只查看要比较的第一个项目; 它忽略了第二项.它无法返回负数,这意味着第一项永远不会被视为"小于"第二项.

用于对列表进行排序的算法恰好在Java 6中工作(毕竟它有50/50的机会),但算法必须在Java 6和Java 8之间进行更改.

您将需要修复您Comparator根据的逻辑compare方法的合同:

比较它的两个参数的顺序.返回负整数,零或正整数,因为第一个参数小于,等于或大于第二个参数.

此外,它不需要是一个Comparator<Object>.把它做成a Comparator<Record>,compare方法可以用Records而不是Objects.

  • 是的,算法改变了.在Java 7*中引入了TimSort*.还有一个系统属性允许恢复旧算法,但由于修复损坏的比较器应该是首选,我不会浪费时间查找该属性的确切名称... (2认同)

SJu*_*n76 5

你的比较器完全坏了.如果它已经工作到现在它是由于纯粹的运气.

如果你这样做compare(a, b)compare(b,a),然后或者

  • a并且b相等,两个调用都返回0

  • a并且b不相等,一个呼叫返回正数而另一个呼叫返回负数.

但是你的比较器永远不会返回负值.这打破了compare合同.您没有设置订单关系.

另一个赠品提示是你只使用r1计算结果......