Java设置奇怪的行为

时间:2012-10-09 15:46:21

标签: java iterator set treeset

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

做这样的事情:

SortedSet<T> groups;

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

不会自动重新排列SortedSet。

在线阅读我发现我需要从集合中删除对象然后再添加它。显然,我在迭代集合时无法做到这一点。所以我决定制作一套Arraylist。将set设置为null,然后再次添加所有元素,以便它们遵循排序顺序。 我做了这样的事情:

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);

感谢。

2 个答案:

答案 0 :(得分: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;
}

}

答案 1 :(得分:0)

  

我发现我需要从集合中删除对象然后   再添加一次。显然,我在迭代集合时无法做到这一点。   所以我决定制作一套Arraylist。

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