2016-07-14 24 views
0

比方说,我有一个具有属性Rank和SubRank的对象的ArrayList。他们通过网络服务传递给我,所以我没有处理最初的订购。如果不存在要使用的子排序,则将其设置为-1。对ArrayList中的特定对象进行排序而不改变Java中的其他对象

[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

您所需的输出逻辑没有意义。你想按“SubRank”排序吗?首先通过“SubRank”,然后是“Rank”?先用'Rank',然后用'SubRank'?无论哪种方式,一个“比较器”(或执行“比较”)将做到这一点。 – Mena

+0

您需要实施“排序数组排序”算法,以SubRank> 0排序对象,并使SubRank <0的对象保持完好。搜索谷歌'排序阵列到位' –

+0

如果列表大小很小,请使用smth类似冒泡排序 - 对于每个位置在列表中找到最小元素并将其与当前元素交换(如果它不是-1) – AdamSkywalker

回答

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++)); 
    } 
} 
+0

这是或多或少我将如何解决问题。谢谢。对不起,我最初没有在OP中提到我的限制。 – benisntfunny

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()); 
} 

OK,只是它的乐趣(和痛苦),这里是一个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; 
} 
+0

我喜欢您的解决方案,但它不是我的选择。我也许应该先说这个,说我正在使用Java 7而不能添加库。它确实让我思考,但我认为我有一种方式,并不是很好,但考虑到我的列表的大小可能会起作用。我可以从列表中提取我的项目,对它们进行排序,每当我点击其中的一个时,重新列出主要列表,在我的子项目中插入任何位置。可能只是用相同的东西替换现有的对象,但没关系。 – benisntfunny

+0

是的,请编辑您的问题以指定这是Java 7,并且您不允许添加库。 – QuantumMechanic

+0

@benisntfunny显然,所有这些都可以在Java 7中完成。只需将lambda扩展为匿名实现即可。番石榴也不是一个硬性要求,但复制这个功能可能是一个非常繁琐的任务 –

相关问题