The task is quite trivial, if you use the correct data structure for it. For this particular task it is java.util.Map. Maps contain key-value pairs (mappings, entries). Then it becomes easy to sort words by frequency, without losing the mapping word -> frequency.
public class Test {
public static void main(String[] args) {
ArrayList<String> words = new ArrayList<>(Arrays.asList("the", "I", "false","too"));
ArrayList<Integer> frequency = new ArrayList<>(Arrays.asList(1, 10, 5, 7));
Map<String, Integer> wordFrequency = new HashMap<>();
for (int i = 0; i < words.size(); i++) {
wordFrequency.put(words.get(i), frequency.get(i));
}
List<String> sortedByFrequency = wordFrequency.entrySet()
.stream()
.sorted((e1, e2) -> Integer.compare(e2.getValue(), e1.getValue()))
.map(Map.Entry::getKey)
.collect(Collectors.toList());
System.out.println(sortedByFrequency);
}
}
Depending on how you populate the lists initially, you can directly populate the Map and not use the lists at all.
Map<String, Integer> wordFrequency = new HashMap<>();
wordFrequency.put("the", 1);
wordFrequency.put("I", 10);
//and so on
Another option would be to use intermediate object to contain the mapping word -> frequency.
public class Pair {
private final String word;
private final int frequency;
//constructor
//getters
}
Then map values in the list to this intermediate object, sort by frequency, extract words, collect.
List<String> sortedByFrequency = IntStream.range(0, words.size())
.mapToObj(i -> new Pair(words.get(i), frequency.get(i)))
.sorted(Comparator.comparing(Pair::getFrequency).reversed())
.map(Pair::getWord)
.collect(Collectors.toList());
System.out.println(sortedByFrequency);
If you are using java 14 or above you can make Pair a record to reduce boilerplate.
public record Pair(String word, int frequency) {
}
//same as example above
.sorted(Comparator.comparing(Pair::frequency).reversed())
.map(Pair::word)
//same as example above