Java 排序对象比较
这是我的目标:Java 排序对象比较,java,object,comparator,comparable,Java,Object,Comparator,Comparable,这是我的目标: public class TrackUserChanges{ private Long id; private Long previous; } 我有一个ArrayList。我想对对象进行如下排序: -若一个对象的getPrevious()等于另一个对象的getId,则将第一个对象(即具有该值的对象)放在getId()上 我在类中已经有一个compareTo方法,我不想破坏它。所以我创建了一个方法: public int compareTrack(TrackUs
public class TrackUserChanges{
private Long id;
private Long previous;
}
我有一个ArrayList。我想对对象进行如下排序:
-若一个对象的getPrevious()等于另一个对象的getId,则将第一个对象(即具有该值的对象)放在getId()上
我在类中已经有一个compareTo方法,我不想破坏它。所以我创建了一个方法:
public int compareTrack(TrackUserChanges o){
if(this.getPrevious().equals((o.getId()))){
return -1;
}
??return this.getPrevious().compareTo(o.getId());
}
这不好。有什么想法吗
示例:id,上一个
TrackUserChanges t = new TrackUserChanges ( 2,1)
TrackUserChanges t1 = new TrackUserChanges ( 3,1)
TrackUserChanges t2 = new TrackUserChanges ( 1,1)
在本例中,t.getPrevious()=t2.getId(),那么我想要这个顺序:t2,t,t1,你要做的不是一个好主意 请阅读合同中的
compareTo()
:
实现者必须确保sgn(比较(x,y))==
-所有x和y的sgn(比较(y,x))。(这意味着当且仅当compare(y,x)抛出异常时,compare(x,y)必须抛出异常
例外情况。)
实施者还必须确保关系是可传递的:
((比较(x,y)>0)和&(比较(y,z)>0))意味着比较(x,z)>0
最后,实现者必须确保compare(x,y)==0意味着
所有z的sgn(比较(x,z))==sgn(比较(y,z))
如果你有a(1,2)
和b(2,1)
,它们不会是自反的:a.compareTo(b)和b.compareTo(a)
都返回相同的符号,这违反了第一条规则
您还没有想到如何处理a(1,2)
和b(3,4)
之间的比较。我怀疑你是否能使它具有及物性和反身性
告诉我们你为什么需要这样做,也许有更好的选择。你必须比较类似的东西
public class TrackUserChanges {
private Long id;
private Long previous;
}
public int compareTrack(TrackUserChanges o) {
int diff = this.getId().compareTo(o.getId());
if (diff != 0) {
return diff;
} else {
return this.getPrevious().compareTo(o.getPrevious());
}
}
您无法将id与上一个id进行比较,即使它们都是长值。您可以按如下方式使用
Comparator
,但出于以下原因,我认为这是不可取的:
// XXX: Untested code
public int compare(TrackUserChanges tuc1, TrackUserChanges tuc2) {
return tuc1.getId() - tuc2.getPreviousId();
}
或者。。。按以前的id然后按当前id排序:
// XXX: Untested code
public int compare(TrackUserChanges tuc1, TrackUserChanges tuc2) {
int cmp = tuc1.getId() - tuc2.getPreviousId();
if (cmp == 0) {
cmp = tuc1.getId() - tuc2.getId();
}
return cmp;
}
但请注意,如果您确实使用了比较器
,则应注意与#equals
的一致性。在您的情况下,这些将是不一致的,因为#equals
应将“like”字段比较为相等。见和。来自比较国:
比较器c对一组元素S施加的顺序称为与equals一致,当且仅当c.compare(e1,e2)==0具有与e1相同的布尔值。S中的每个e1和e2都具有equals(e2)
当使用比较器时,应谨慎使用,比较器能够对排序集(或排序映射)施加与等于不一致的排序。假设一个带有显式比较器c的排序集(或排序映射)与从集合S中提取的元素(或键)一起使用。如果c对S施加的顺序与equals不一致,则排序集(或排序映射)的行为将“奇怪”。特别是排序集(或排序映射)将违反集合(或映射)的一般约定,它的定义是平等的
因此,如果计划使用已排序的集合,则不能使用Comparator
。您是否可以选择按#以前的id
然后按id
排序,如下所示:
// XXX: Untested code
public int compare(TrackUserChanges tuc1, TrackUserChanges tuc2) {
int cmp = tuc1.getPreviousId() - tuc2.getPreviousId();
if (cmp == 0) {
cmp = tuc1.getId() - tuc2.getId();
}
return cmp;
}
这将自然地仅按先前的id(然后是id)排序。因此,对于:
TrackUserChanges t = new TrackUserChanges(2,1); //id, previousId
TrackUserChanges t1 = new TrackUserChanges(3,1);
TrackUserChanges t2 = new TrackUserChanges(1,1);
你仍然会得到:
t2,t,t1
用于:
您将获得(按previousId
排序,然后按id
排序):
(以前的ID=1)t2,t,t1,t5,
(以前的ID=2)t3,t4
这将使您能够实现一个一致的
比较,以和#equals
用于SortedSet
和TreeMap
。我不理解“将第一个对象和具有该值的对象放在getId()上”这一部分。我想您要做的是this.getPrevious().getId()==o.getId()
;不假设Id是基元。您还可以创建一个比较器,它将保存compareTrack
排序逻辑。@Smutje我想以这样一种方式排序,即我将在getPrevious()中找到的Id放在第一位。示例:Id,previous TrackUserChanges t=new TrackUserChanges(2,1)TrackUserChanges t1=new TrackUserChanges(3,1)TrackUserChanges t2=new-TrackUserChanges(1,1)在本例中,t.getPrevious()=t2.getId(),那么我想要这个顺序:t2,t,t1
TrackUserChanges t3 = new TrackUserChanges(5,2); //id, previousId
TrackUserChanges t4 = new TrackUserChanges(6,2);
TrackUserChanges t5 = new TrackUserChanges(7,1)