13

I have a list of objects in java that looks something like this:

List<Video> videos = new ArrayList<Video>();

and my video object looks like this:

public class Video {
    private String nameId;
    private Integer id;
    ...
}

I have another list that just has my nameId strings:

List<String> nameIdList = ArrayList<String>();

How can I write a compareto method that doesn't sort my list of videos by comparing each video and instead uses another list? My approach so far has been to use a simple bubble sort but that will be very inefficient as my list gets bigger

Example:

I could have video objects with nameIds : "apple", "bannana", "orange"

and my list of strings to sort them by could be: "bannana", "apple", "orange"

so my videos I would want to return to my client should be in the order of: "bannana", "apple", "orange"

DanielD
  • 1,315
  • 4
  • 17
  • 25

6 Answers6

30

Java 8:

videos.sort(Comparator.comparing(v->nameIdList.indexOf(v.getNameId())));

this is smaller than this

Tokala Sai Teja
  • 650
  • 8
  • 9
5

A simple and clean solution, which surprisingly has not been mentioned:

videos.sort(Ordering.explicit(nameIdList).onResultOf(Video::getNameId));

Ordering.explicit is part of Guava.

amurka
  • 645
  • 1
  • 6
  • 14
2

You could use a custom Comparator

List<String> nameIdList = new ArrayList<>();
Comparator<Video> compare = new Comparator<Video>() {
     public int compare(Video v1, Video v2) {
         return nameIdList.indexOf(v1.getNameId()) - nameIdList.indexOf(v2.getNameId());
     }
};

To make this more efficient you could have a Map<String, Integer> so you can look up the desired order more efficiently.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
2

Unless the lists involved are very long, I would use this solution, but here is an alternative solution that has time complexity O(n). Any solution using a Comparator together with Collections.sort or Arrays.sort has time complexity no better than O(n log n).

The method sorts the list videos based on the other list, and clears away any Video whose nameId is not in the list.

public static void sort(List<Video> videos, List<String> list) {
    Map<String, List<Video>> map = new HashMap<>();
    for (String string : list)
        map.put(string, new ArrayList<>());
    for (Video video : videos) {
        List<Video> value = map.get(video.getNameId());
        if (value != null)
            value.add(video);
    }
    videos.clear();
    for (String string : list)
        for (Video video : map.get(string))
            videos.add(video);
}
Community
  • 1
  • 1
Paul Boddington
  • 37,127
  • 10
  • 65
  • 116
2

Java 8. Convert to map and pick by hash:

Map<String, Video> videoMap = videos.stream()
         .collect(Collectors.toMap(Video::getNameId, v -> v));

return videos.stream()
         .map(v -> videoMap.get(v))
         .collect(Collectors.toList());
Yaro
  • 614
  • 6
  • 13
1

You can use Java 8 stream

List<Video> orderedList=
              nameIdList.stream()
                  .map(
                      s ->
                          videos.stream()
                              .filter(v -> v.get_id().equals(s))
                              .findFirst()
                              .orElse(null))
                  .collect(Collectors.toList());
              
MA-Dev
  • 101
  • 2
  • 11