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"
Java 8:
videos.sort(Comparator.comparing(v->nameIdList.indexOf(v.getNameId())));
this is smaller than this
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.
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.
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);
}
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());
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());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.