2012-10-09 1 views
1

일부 조건에 따라 정렬 된 세트의 비교 가능한 값을 변경해야하는 문제가있었습니다. 이 같은Java 이상한 동작 설정

이렇게 뭔가 :

SortedSet<T> groups; 

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

자동 된 SortedSet를 다시 정렬하지 않음.

온라인 읽기 나는 세트에서 대상을 제거하고 다시 추가해야한다는 것을 알았습니다. 분명히, 세트를 반복하면서 나는 그것을 할 수 없다. 그래서 나는 세트의 Arraylist를 만들기로 결정했다. 세트를 null로 한 다음 모든 요소를 ​​다시 추가하여 정렬 된 순서를 따르십시오. 다음과 같이했습니다 :

SortedSet 그룹; 내가 확인할 때 나는 이런 식으로 뭔가하려고 할 때

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

groups = new TreeSet<T>(groupList); 

은 그러나 그룹은 객체 T

의 순서를 비교 비교 기준으로 정렬 순서에 따라 didnt는 설정하지만 :

SortedSet의 그룹;

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

groups.addAll(groupList); 

예상대로 결과를 얻었습니다. 누군가 나에게 무슨 일이 일어 났는지 설명 할 수 있습니까?

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

감사

이 내가 사람들을 위해

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

} 

이 완료 프로그램을보고 싶어 내 클래스 T 구현 한 방법이다.

+1

문제를 설명하는 짧지 만 완전한 * 프로그램을 보여주십시오.예를 들어'SortedSet '이 커스텀 비교기를 사용했는지 또는 일반적인 'Comparable '구현을 사용했는지 알 수 없다. –

+0

당신이 제시 한 방식대로, 두 가지 방법 모두 잘 작동했을 것입니다. – dasblinkenlight

+1

다른 것들과는 달리, 당신의 compareTo 메소드는 오버플로로 인해 깨졌습니다. 그리고 여러분이 보여준 샘플은 * 모든 * 값의 서수를 같은 값으로 설정합니다. 다시 말하지만, 짧지 만 완전한 프로그램은 ... –

답변

0

사용자가 제공해야 TreeSet 계약에 따라 또한
@Override 
public int compareTo(CustomObject o) { 
    return Integer.valueOf(o.ordinal).compareTo(ordinal); 
} 

는 compareTo 메소드

@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; 
} 

샘플 구현과 동기화 될 것입니다 방법을 동일 아래에 compareTo 메소드를 변경

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

} 
+0

.equals 메서드를 재정의해야하지만 .hashcode 메서드도 재정의해야합니다. 그렇지 않으면 전체 작업이 중단됩니다. 해시 코드는 내부 해시 맵과 함께 작동하며, .equals 메서드와 .hashcode 메서드가 일치하지 않으면 (즉, 평등을 결정하는 데 사용되는 필드가 해시 코드 생성의 일부일 필요가있는 경우) 데이터 구조가 중단됩니다. 귀하의 경우 Integer.valueOf (ordinal) .hashcode()에 메서드를 위임 할 수 있습니다. – Matt

+0

@Matt Question은 TreeSet에 관한 것이므로 hashCode가 포함되었습니다. 해시는 HashSet 및 HashMap에만 필요하므로 지금 hashCode를 포함 시켰습니다. 그러나 그렇습니다. 가지고 있으면 좋으며 추가하기 쉽습니다. –

+0

서문이 항상 부정적이지 않을 것이라고 확신하기 때문에 compareTo 메서드가 괜찮다고 생각합니다. –

0

나는 세트에서 대상을 제거해야한다고 생각하고 다시 추가하십시오. 분명히, 세트를 반복하면서 나는 그것을 할 수 없다. 그래서 나는 세트의 Arraylist를 만들기로 결정했습니다.

maintaining TreeSet sort as object changes value에서 내 대답을보고 내 UpdateableTreeSet 구현을 시도하십시오. 정렬 된 집합을 반복하면서 지연된 업데이트를 수행 할 수 있습니다.