假设我有一个具有属性Rank和SubRank的对象的ArrayList。它们通过Web服务传递给我,所以我没有处理初始订购。如果没有要使用的subrank,则将其设置为-1。
[Rank: 1, SubRank: -1]
[Rank: 2, SubRank: -1]
[Rank: 3, SubRank: 3]
[Rank: 4, SubRank: 2]
[Rank: 5, SubRank: -1]
[Rank: 6, SubRank: 1]
我需要做的是使用SubRank对任何内容进行排序,只留下剩余的对象,所以列表最终看起来像:
[Rank: 1, SubRank: -1]
[Rank: 2, SubRank: -1]
[Rank: 6, SubRank: 1]
[Rank: 4, SubRank: 2]
[Rank: 5, SubRank: -1]
[Rank: 3, SubRank: 3]
限制:Java 7,没有外部库
答案 0 :(得分:2)
由于OP已经提到他仅限于Java 7并且没有添加任何库......
制作一个新的List
,其中只包含SubRank > -1
的项目。然后对List
进行排序。然后迭代原始列表,当您到达具有SubRank > -1
的项目时,将其替换为已排序列表中的相应项目。
List<Item> sortedItems = new ArrayList<>();
for (Item item : items) {
if (item.subRank > -1) {
sortedItems.add(item);
}
}
Collections.sort(sortedItems,
new Comparator<Item>()
{
@Override
public int compare(Item lhs, Item rhs) {
return Integer.compare(lhs.SubRank, rhs.SubRank);
}
});
int sortedIndex = 0;
for (int i; i < items.size(); i++) {
if (items.get(i).subRank > -1) {
items.set(i, sortedItems.get(sortedIndex++));
}
}
答案 1 :(得分:1)
这不是微不足道的。 根据Rank,您可能必须将列表拆分为子列表,然后按子排序对这些子列表进行排序并再次加入。
使用自定义Guava Multimap:
,只需少量疼痛即可完成public static List<Item> sortBySubRank(List<Item> unsorted) {
// custom multimap that preserves key order, but sorts values
// by supplied comparator
Multimap<Integer, Item> itemsByrank = Multimaps.newMultimap(
new LinkedHashMap<>(),
// collection supplier
() -> new TreeSet<>(
// custom comparator
(Comparator<Item>) (o1, o2) -> Integer.compare(o1.subRank, o2.subRank))
);
// store in multimap
unsorted.forEach((i) -> itemsByrank.put(i.rank, i));
// retrieve sorted values
return ImmutableList.copyOf(itemsByrank.values());
}
好的,只是为了它的乐趣(和痛苦),这里是没有Guava的Java 7版本基本上做同样的事情:
public static List<Item> sortBySubRankInJava7(List<Item> unsorted) {
Map<Integer,Set<Item>> map = new LinkedHashMap<>();
Comparator<Item> comparator=new Comparator<Item>() {
@Override public int compare(Item o1, Item o2) {
return Integer.compare(o1.subRank, o2.subRank);
}
};
for (Item item : unsorted) {
if (map.containsKey(item.rank)) {
map.get(item.rank).add(item);
} else {
TreeSet<Item> set = new TreeSet<>(comparator);
set.add(item);
map.put(item.rank, set);
}
}
List<Item> result = new ArrayList<>(unsorted.size());
for (Set<Item> items : map.values()) {
result.addAll(items);
}
return result;
}