In Java How to Sort One List Based on Another

Sorting list based on another list's order

An efficient solution is to first create the mapping from the ID in the ids (your desired IDs order) to the index in that list:

val orderById = ids.withIndex().associate { it.value to it.index }

And then sort your list of people by the order of their id in this mapping:

val sortedPeople = people.sortedBy { orderById[it.id] }

Note: if a person has an ID that is not present in the ids, they will be placed first in the list. To place them last, you can use a nullsLast comparator:

val sortedPeople = people.sortedWith(compareBy(nullsLast<String>) { orderById[it.id] })

Order a list based on another list Java

I would just use a map with indexes of each name, to simplify the lookup:

Map<String, Integer> indexOfMap = IntStream.range(0, list2.size())
.mapToObj(i -> Map.entry(list2.get(i).getName(), i))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));

Then implement a Comparator that sorts by looking up names in indexOfMap:

Comparator<Employee> comparator = (a, b) -> 
indexOfMap.containsKey(a.getName()) && indexOfMap.containsKey(b.getName())
? indexOfMap.get(a.getName()) - indexOfMap.get(b.getName())
: (!indexOfMap.containsKey(a.getName()) ? -1 : 1);

//you can make a copy of list if you don't want to change it
//or you can stick to your stream and just use sorted with the comparator
list.sort(comparator);

Note that the order of the first elements in the resulting list is not deterministic (because it's just all elements not present in list2, with no further ordering). All of the values at the end of the list will be in their order dictated by the list2.

Sort list based on specific order in java

This can be elegantly solved with guava's Ordering.explicit:

Collections.sort(carList, Ordering.explicit(preOrderedList).onResultOf(new Function<Car, String>() {
@Override
public String apply(Car car) {
return car.getName();
}
}));

The last version of Guava thas supports Java 6 is Guava 20.0:

<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>20.0</version>
</dependency>

Java sort one list based on another list

  1. First create a map, with sortedItem.name to its first index in the list

    AtomicInteger index = new AtomicInteger();   
    // keep first index with (oldV, newV) -> oldV
    Map<String, Integer> map = values.stream()
    .collect(Collectors.toMap(s -> s.getName(), s -> index.getAndIncrement(), (oldV, newV) -> oldV));
  2. Then use it to sort the list

    listA.sort(Comparator.comparingInt(pair -> map.get(pair.getFirst())));


List<SortedItem> sortedList = [
SortedItem(name=B, sortIndex=0),
SortedItem(name=A, sortIndex=1),
SortedItem(name=C, sortIndex=2),
SortedItem(name=C, sortIndex=3),
SortedItem(name=D, sortIndex=4)
]
// becomes the map
{A=1, B=0, C=2, D=4}

Java Sort a list based on another list

You can setup history as a HashMap or separate class to make this easier. But because you also like to be able to sort history based on frequency, I would recommend a History class:

class Move {

int from, to;

@Override
public int hashCode() {
return from + (to * 100);
}

@Override
public boolean equals(Object o) {
return (o instanceof Move
&& ((Move) o).from == from
&& ((Move) o).to == to);
}
}

class History extends Move implements Comparable<History> {

int frequency;

public History(Move m) {
from = m.from;
to = m.to;
frequency = 1;
}

public void increment() {
frequency += 1;
}

public int compareTo(History h) {
// to be able to sort it in a TreeSet descending on frequency
// note that it is not resorted if you change frequencies, so
// build the set, and then convert it to a TreeSet afterwards.
return (frequency == h.frequency) ? 1 : (h.frequency - frequency);
}
}

Then create a HashMap to quickly fill history, and convert it into a TreeSet to sort:

  List<Move> moves = board.getMoves();
HashMap<History, History> fillTable = new HashMap<History, History>();
for (Move m : moves) {
History h = fillTable.get(m);
if (h == null) {
h = new History(m);
fillTable.put(h, h);
} else {
h.increment();
}
}
TreeSet<History> sorted = new TreeSet<History>(fillTable.values());
.... ready to use


Related Topics



Leave a reply



Submit