The problem with indexOf()
is that it returns the index of the first occurrence of the element in the list, or -1
if not present. If your list has duplicates, then, for these duplicates, you'll get the index of their first occurrence within the list.
There are many ways to accomplish what you want. One is to use a SortedSet
and a helper IndexedEntry
class:
public class IndexedEntry<T extends Comparable<T>>
implements Comparable<IndexedEntry<T>> {
private final Integer index;
private final T entry;
public IndexedEntry(Integer index, T entry) {
this.index = index;
this.entry = entry;
}
public Integer getIndex() {
return this.index;
}
public T getEntry() {
return this.entry;
}
@Override
public int compareTo(IndexedEntry<T> other) {
int byEntry = this.getEntry().compareTo(other.getEntry());
if (byEntry == 0) {
return this.getIndex().compareTo(other.getIndex());
}
return byEntry;
}
@Override
public String toString() {
return "(" + this.entry + ", " + this.index + ")";
}
}
The IndexedEntry
class simply wraps a Comparable
value and its index, and implements Comparable
by first comparing the value, and if the value is equal, then it compares the index. This means that an ordered list of IndexedEntry
will have its elements ordered by (value, index)
.
To use the IndexedEntry
class, just iterate over your collection, create an IndexedEntry
for each element by wrapping the element and its index, and then sort the list of IndexedEntry
:
List<Float> unordered = new ArrayList<>(Arrays.asList(3.2f, 1.0f, 7.5f, 3.2f, 0.8f));
System.out.println(unordered); // [3.2, 1.0, 7.5, 3.2, 0.8]
List<IndexedEntry<Float>> ordered = new ArrayList<>();
for (int i = 0; i < unordered.size(); i++) {
IndexedEntry<Float> entry = new IndexedEntry<>(i, unordered.get(i));
ordered.add(entry);
}
Collections.sort(ordered);
System.out.println(ordered); // [(0.8, 4), (1.0, 1), (3.2, 0), (3.2, 3), (7.5, 2)]
Once sorted, the ordered
list will contain the elements along with the original index.