내 간단한 비교기가 깨진 이유는 무엇입니까?
문제
나는 이것을 단순화 한 수업이 있습니다.
final class Thing {
private final int value;
public Thing(int value) {
this.value = value;
}
public int getValue() {
return value;
}
@Override public String toString() {
return Integer.toString(value);
}
}
나는 이것의 배열을 정렬하고 싶다. 그래서 나는 간단한 copmarator를 만들었습니다.
private static final Comparator<Thing> reverse = new Comparator<Thing>() {
public int compare(Thing a, Thing b) {
return a.getValue() - b.getValue();
}
};
그런 다음 두 인수 형식을 사용합니다 Arrays.sort
.
이것은 내 테스트 사례에 적합하지만 때로는 배열이 이상하지만 반복 가능한 순서로 끝나는 경우가 종종 있습니다. 어떻게 이럴 수있어?
해결책
정수 오버플로… 또는 더 정확하게, 언더 플로.
대신 명시 적 비교를하십시오.
private static final Comparator<Thing> reverse = new Comparator<Thing>() {
public int compare(Thing a, Thing b) {
int av = a.getValue(), bv = b.getValue();
return (av == bv) ? 0 : ((av < bv) ? -1 : +1);
}
};
차이가 "래핑"하지 않을 것이라고 확신한다면 뺄셈을 사용하는 것이 좋습니다. 예를 들어, 해당 값이 음성이 아닌 것으로 제한되는 경우.
다른 팁
마이너스를 사용하여 비교를 만들 수 없습니다. 절대적인 차이가 초과되면 오버플로됩니다 Integer.MAX_VALUE
.
대신이 알고리즘을 사용하십시오.
int compareInts( int x, int y ) {
if ( x < y ) return -1;
if ( x > y ) return 1;
return 0;
}
나는 그러한 목적을 위해이 기능을 라이브러리에 갖고 싶습니다.
노력하다
System.out.println(Integer.MAX_Value - Integer.MIN_VALUE);
이것은 max_value> min_value로 양수를 반환해야하지만 대신 -1 인쇄합니다.
Java Primitives를 비교할 때, 그들을 객체로 변환하고 그들의 compareTo()
행동 양식.
이 경우 할 수 있습니다.
return Integer.valueOf(a.getValue()).compareTo(b.getValue())
의심스러운 경우 잘 테스트 한 라이브러리를 사용하십시오.
거기에 어떤 종류의 숫자를 던지십니까? 숫자가 충분히 크면 정수의 최소/최대 값을 감싸고 엉망으로 끝날 수 있습니다.
A의 가치가 매우 부정적이고 B의 가치가 매우 긍정적이라면 대답은 매우 잘못 될 것입니다.
IIRC, int 오버플로는 JVM에서 조용히 감싸고 있습니다.
- Markusq