Der folgende Code ist eine bearbeitete Version von Dave Koelle's AlphanumComparator. Die Bearbeitung enthält Code, der leere Strings an das Ende der Liste oder den unteren Rand der JTable
in meinem Fall sortiert. Das Problem ist ein java.lang.IllegalArgumentException: Comparison method violates its general contract!
tritt auf.Vergleicher, der den allgemeinen Vertrag verletzt
Um mein Problem zu beheben, schaute ich hinein und fand Gründe wie der Komparator return 0;
an der richtigen Stelle nicht. Ich fand auch einen Kommentar in der Java bug database die
Der Sortieralgorithmus von java.util.Arrays.sort zu lesen und (indirekt) durch java.util.Collections.sort ersetzt. Die neue Sortierimplementierung kann eine IllegalArgumentException auslösen, wenn sie eine Vergleichstabelle entdeckt, die den Vergleichsvertrag verletzt. Die vorherige Implementierung ignorierte eine solche Situation stillschweigend. Wenn das vorherige Verhalten gewünscht ist, können Sie die neue Systemeigenschaft verwenden, java.util.Arrays.useLegacyMergeSort,
vorheriges mergesort Verhalten
import java.util.Comparator;
import javax.swing.JTable;
import javax.swing.SortOrder;
public class AlphanumComparator implements Comparator<String> {
JTable table;
public AlphanumComparator(JTable table) {
this.table = table;
}
private final boolean isDigit(char ch) {
return ch >= 48 && ch <= 57;
}
private final String getChunk(String s, int slength, int marker) {
StringBuilder chunk = new StringBuilder();
char c = s.charAt(marker);
chunk.append(c);
marker++;
if (isDigit(c)) {
while (marker < slength) {
c = s.charAt(marker);
if (!isDigit(c))
break;
chunk.append(c);
marker++;
}
} else {
while (marker < slength) {
c = s.charAt(marker);
if (isDigit(c))
break;
chunk.append(c);
marker++;
}
}
return chunk.toString();
}
public int compare(String s1, String s2) {
boolean swapInt = table.getRowSorter().getSortKeys().get(0).getSortOrder() == SortOrder.ASCENDING;
int thisMarker = 0;
int thatMarker = 0;
int s1Length = s1.length();
int s2Length = s2.length();
if(s1Length != 0 && s2Length != 0) {
while (thisMarker < s1Length && thatMarker < s2Length) {
String thisChunk = getChunk(s1, s1Length, thisMarker);
thisMarker += thisChunk.length();
String thatChunk = getChunk(s2, s2Length, thatMarker);
thatMarker += thatChunk.length();
int result = 0;
if (isDigit(thisChunk.charAt(0)) && isDigit(thatChunk.charAt(0))) {
int thisChunkLength = thisChunk.length();
result = thisChunkLength - thatChunk.length();
if (result == 0) {
for (int i = 0; i < thisChunkLength; i++) {
result = thisChunk.charAt(i) - thatChunk.charAt(i);
if (result != 0) {
return result;
}
}
}
} else {
result = thisChunk.compareTo(thatChunk);
}
if (result != 0)
return result;
}
return s1Length - s2Length;
} else {
if(swapInt) {
if(s1Length == 0) {
return 1;
} else {
return -1;
}
} else {
if(s1Length == 0) {
return -1;
} else {
return 1;
}
}
}
}
}
wiederherzustellen
Würde jemand in der Lage sein, mein Problem zu helfen, zu beheben und erklären, warum dieser Komparator verletzt den vergleichbaren Vertrag
Ausnahme-Stack-Trace benötigt, wenn
Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:744)
at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:481)
at java.util.ComparableTimSort.mergeForceCollapse(ComparableTimSort.java:422)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:222)
at java.util.Arrays.sort(Arrays.java:1246)
at javax.swing.DefaultRowSorter.sort(DefaultRowSorter.java:607)
at javax.swing.DefaultRowSorter.setSortKeys(DefaultRowSorter.java:319)
at javax.swing.DefaultRowSorter.toggleSortOrder(DefaultRowSorter.java:480)
at javax.swing.plaf.basic.BasicTableHeaderUI$MouseInputHandler.mouseClicked(BasicTableHeaderUI.java:112)
at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:270)
at java.awt.Component.processMouseEvent(Component.java:6538)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6300)
at java.awt.Container.processEvent(Container.java:2236)
at java.awt.Component.dispatchEventImpl(Component.java:4891)
at java.awt.Container.dispatchEventImpl(Container.java:2294)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4534)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
at java.awt.Container.dispatchEventImpl(Container.java:2280)
at java.awt.Window.dispatchEventImpl(Window.java:2750)
at java.awt.Component.dispatchEvent(Component.java:4713)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
haben Sie Beispiele für Eingabe? – Tibrogargan