1

我遇到了一个问题,我需要根据某些条件更改排序集的可比较值。

做这样的事情:

SortedSet<T> groups;

for(T t: groups){
        t.setOrdinal(max);
}

不会自动重新排列 SortedSet。

在线阅读我发现我需要从集合中删除对象然后再次添加它。显然,在迭代集合时我不能这样做。所以我决定制作一个数组列表。使集合为空,然后再次添加所有元素,以便它们遵循排序顺序。我做了这样的事情:

SortedSet 组;

List<T> groupList = new ArrayList<T>(groups);
groups = null;
for(T t: groupList){
        t.setOrdinal(max);
}

groups = new TreeSet<T>(groupList);

但是当我检查组集时,它没有遵循基于比较对象 T 序数的比较器的排序顺序

但是当我尝试这样的事情时:

SortedSet 组;

List<T> groupList = new ArrayList<T>(groups);
groups.clear();
for(T t: groupList){
        t.setOrdinal(max);
}

groups.addAll(groupList);

我得到了预期的结果。有人可以解释一下发生了什么吗?

这就是我实现我的 T 类的方式

public class T implements Serializable, Comparable<T> {
//
int ordinal;
//getter
//setter

 @Override
  public int compareTo(T that) {
    if (that == null) {
      return 1;
    }

    return this.ordinal - that.ordinal;
  }

}

对于那些想看到完整程序的人:

List<SmartUser> groupsList = new ArrayList<SmartUser>(groups);
groups = null;
for (SmartUser smartUser : groupsList) {
        if (smartUser.isExpired()) {
                smartUser.setOrdinal(Long.MAX_VALUE);
        }
        SmartUserQuery smartUserQuery = smartUser.getSmartUserQuery();
        if (smartUserQuery != null) {
                //Do parallel processing: of each samrtUser
        }
}

groups = new TreeSet<SmartUser>groupsList;

正确的结果给出方法:

List<SmartUser> groupsList = new ArrayList<SmartUser>(groups);
groups.clear();
for (SmartUser smartUser : groupsList) {
        if (smartUser.isExpired()) {
                smartUser.setOrdinal(Long.MAX_VALUE);
        }
        SmartUserQuery smartUserQuery = smartUser.getSmartUserQuery();
        if (smartUserQuery != null) {
                //Do parallel processing: of each samrtUser
        }
}

groups.addAll(groupsList);

谢谢。

4

2 回答 2

0

我发现我需要从集合中删除该对象,然后再次添加它。显然,在迭代集合时我不能这样做。所以我决定制作一个数组列表。

看看我在维护 TreeSet sort as object changes value的答案并尝试我的UpdateableTreeSet实现。它允许您在迭代排序集时执行延迟更新。

于 2012-10-27T10:44:21.417 回答
0

将您的 compareTo 方法更改为以下

@Override
public int compareTo(CustomObject o) {
    return Integer.valueOf(o.ordinal).compareTo(ordinal );
}

同样根据TreeSet合同,您应该提供与 compareTo 方法同步的 equals 方法

 @Override
public boolean equals(Object obj) {
    if (obj == null)
        return false;
    if (!(obj instanceof CustomObject))
        return false;
    CustomObject o = (CustomObject) obj;

    return this.ordinal == o.ordinal;
}

示例实现

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;

public class CustomObject implements Comparable<CustomObject> {

private int ordinal = 0;

public CustomObject(int priority) {
    this.ordinal = priority;
}

/**
 * @param args
 */
public static void main(String[] args) {

    List<CustomObject> list = new ArrayList<CustomObject>();
    list.add(new CustomObject(1));
    list.add(new CustomObject(2));
    list.add(new CustomObject(3));
    list.add(new CustomObject(6));
    list.add(new CustomObject(4));
    System.out.println("Before: " + list);
    for (CustomObject object : list) {
        if (object.ordinal == 4) {
            object.ordinal = 10;
        }
    }
    Set<CustomObject> set = new TreeSet<CustomObject>();
    set.addAll(list);
    System.out.println("After: " + set);

}

@Override
public int compareTo(CustomObject o) {
    return Integer.valueOf(o.ordinal).compareTo(ordinal);
}

@Override
public boolean equals(Object obj) {
    if (obj == null)
        return false;
    if (!(obj instanceof CustomObject))
        return false;
    CustomObject o = (CustomObject) obj;

    return this.ordinal == o.ordinal;
}

@Override
public String toString() {
    return " Ordinal Value is :" + ordinal;
}

}
于 2012-10-09T16:01:03.003 回答