Le code ci-dessous est une version éditée de Dave Koelle's AlphanumComparator. L'édition contient du code qui trie les chaînes vides à la fin de la liste, ou au bas de la JTable
dans mon cas. Le problème est java.lang.IllegalArgumentException: Comparison method violates its general contract!
se produit.Contrat de violation de contrat général
Pour résoudre mon problème, je l'ai examiné et trouvé des raisons telles que le comparateur n'a pas un return 0;
au bon endroit. J'ai aussi trouvé un commentaire dans Java qui bug database lu
L'algorithme de tri utilisé par java.util.Arrays.sort et (indirectement) par java.util.Collections.sort a été remplacé. La nouvelle implémentation de tri peut lancer une exception IllegalArgumentException si elle détecte un objet comparable qui viole le contrat comparable. L'implémentation précédente ignorait silencieusement une telle situation. Si le comportement précédent est désiré, vous pouvez utiliser la nouvelle propriété du système, java.util.Arrays.useLegacyMergeSort, pour rétablir le comportement précédent mergesort
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;
}
}
}
}
}
Quelqu'un capable d'aider à résoudre mon problème et expliquer pourquoi ce comparateur viole le contrat comparable
Exception trace de pile si nécessaire
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)
avez-vous des exemples d'entrée? – Tibrogargan