To make this simple, I have a method which looks up a group of keys in a hash table and insert found ones into an arraylist. The object type associated with the arraylist is the following:
public class PartitionEdge implements Comparable<PartitionEdge>
{
public void setWeight(float weight)
{
this.weight = weight;
}
public float getWeight()
{
return this.weight;
}
public void setId(int id)
{
this.id = id;
}
public int getId()
{
return this.id;
}
public void setFrom(PartitionVertex from)
{
this.from = from;
}
public PartitionVertex getFrom()
{
return this.from;
}
public void setTo(PartitionVertex to)
{
this.to = to;
}
public PartitionVertex getTo()
{
return this.to;
}
public void setLabel(int label)
{
this.label = label;
}
public int getLabel()
{
return this.label;
}
public int PathLength = 0;
protected int id;
protected PartitionVertex from;
protected PartitionVertex to;
protected float weight;
protected int label;
@Override
public int compareTo(PartitionEdge e) {
//return Integer.compare(this.label, e.label);
return Float.compare(this.weight, e.weight);
}
}
It uses the default comparator from the Float class. But in a method where I try to call sort, one of the following exceptions will occur (originally only the one in the title).
Exception in thread "Thread-3" Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.base/java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:870)
at java.base/java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:487)
at java.base/java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:413)
at java.base/java.util.ComparableTimSort.sort(ComparableTimSort.java:213)
at java.base/java.util.Arrays.sort(Arrays.java:1107)
at java.base/java.util.Arrays.sort(Arrays.java:1301)
at java.base/java.util.ArrayList.sort(ArrayList.java:1721)
at java.base/java.util.Collections.sort(Collections.java:145)
at dedp.DistanceOracles.BridgeEdgeDOThread.run(BridgeEdgeDOThread.java:44)
java.util.ConcurrentModificationException
at java.base/java.util.ArrayList.sort(ArrayList.java:1723)
at java.base/java.util.Collections.sort(Collections.java:145)
at dedp.indexes.edgedisjoint.ConnectedComponent.checkBridgeDO(ConnectedComponent.java:151)
at dedp.Test.BridgeThreadTest.test1(BridgeThreadTest.java:109)
at dedp.Test.BridgeThreadTest.main(BridgeThreadTest.java:122)
Exception in thread "Thread-4" Exception in thread "main" java.util.ConcurrentModificationException
at java.base/java.util.ArrayList.sort(ArrayList.java:1723)
at java.base/java.util.Collections.sort(Collections.java:145)
at dedp.indexes.edgedisjoint.ConnectedComponent.checkBridgeDO(ConnectedComponent.java:152)
at dedp.Test.BridgeThreadTest.test1(BridgeThreadTest.java:109)
at dedp.Test.BridgeThreadTest.main(BridgeThreadTest.java:122)
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.base/java.util.ComparableTimSort.mergeLo(ComparableTimSort.java:748)
at java.base/java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:485)
at java.base/java.util.ComparableTimSort.mergeCollapse(ComparableTimSort.java:413)
at java.base/java.util.ComparableTimSort.sort(ComparableTimSort.java:213)
at java.base/java.util.Arrays.sort(Arrays.java:1107)
at java.base/java.util.Arrays.sort(Arrays.java:1301)
at java.base/java.util.ArrayList.sort(ArrayList.java:1721)
at java.base/java.util.Collections.sort(Collections.java:145)
at dedp.DistanceOracles.BridgeEdgeDOThread.run(BridgeEdgeDOThread.java:44)
The following is my original code where the exception is raised:
public boolean checkBridgeDO(PartitionVertex source, ArrayList<PartitionEdge>bridgeList) throws ObjectNotFoundException {
HashMap<Integer, PartitionVertex> potentialBridgeDestinations = new HashMap<>();
boolean got=true;
for(Map.Entry<Integer, PartitionVertex>set:bridgeVertices.entrySet()){
float result= this.lookUp(source, set.getValue());
if(result<0) {
potentialBridgeDestinations.put(set.getKey(), set.getValue());
got = false;
}else{
PartitionEdge e = new PartitionEdge();
e.setFrom(source);
e.setTo(set.getValue());
e.setWeight(result);
e.setLabel(this.partition.Label);
bridgeList.add(e);
}
}
if(!got){
source.lock.lock();
source.thread=new BridgeEdgeDOThread();
source.underBridgeComputation=true;
source.thread.setParameters(this,source,potentialBridgeDestinations,bridgeList,0);
source.thread.start();
source.lock.unlock();
}
Collections.sort(bridgeList);
return got;
}
Here the thread is trying to add more entries to the arraylist.