使用预定义顺序对Java ArrayList进行排序

5

我有一个未排序的列表,但我想以自定义方式进行排序,例如:

item_one_primary.pls
item_one_secondary.pls
item_one_last.pls

item_two_last.pls
item_two_primary.pls
item_two_secondary.pls

item_three_secondary.pls
item_three_last.pls
item_three_primary.pls

这是我的预定义顺序:primary, secondary, last 应用排序后,上面无序列表应该是这样的:
item_one_primary.pls
item_one_secondary.pls
item_one_last.pls

item_two_primary.pls
item_two_secondary.pls
item_two_last.pls

item_three_primary.pls
item_three_secondary.pls
item_three_last.pls

我尝试使用比较器,但最终得到了这样的结果:

item_one_primary.pls
item_two_primary.pls
item_three_primary.pls

有人知道如何解决这个问题吗?

以下是我使用的一些代码:

List<String> predefinedOrder;

public MyComparator(String[] predefinedOrder) {
        this.predefinedOrder = Arrays.asList(predefinedOrder);
    }

@Override
    public int compare(String item1, String item2) {
        return predefinedOrder.indexOf(item1) - predefinedOrder.indexOf(item2);
    }   

我没有包含拆分操作(首先按点(.)拆分,然后按下划线(_)拆分以获取预排序列表中的项)。


3
你使用 Comparator 是正确的方向。请展示你的代码。 - Jim Garrison
2
让我们来看看你尝试编写的比较器。 - Jonathon Faust
1
大家好,问题的赞应该表示这个问题有趣且写得好。在原始发布者添加代码之前,请不要点赞。 - Jim Garrison
2个回答

5

您需要使用一个比较器Comparator,首先检查项目编号,只有在它们相等的情况下才检查您预定义的顺序

尝试像这样:

public int compare(Object o1, Object o2) {
        String s1 = (String) o1;
        String s2 = (String) o2;

        String[] a1 = s1.split("_");
        String[] a2 = s2.split("_");

         /* If the primary elements of order are equal the result is 
         the order of the second elements of order */ 
        if (a1[1].compareTo(a2[1]) == 0) { 
            return a1[2].compareTo(a2[2]); 
        /* If they are not equal, we just order by the primary elements */
        } else {
            return a1[1].compareTo(a2[1]);
        }
    }

这只是一个基本示例,加入一些额外的错误检查会更好。


2
使用Google Guava API的解决方案能够得出简单易读的结果:
    // some values
    List<String> list = Lists.newArrayList("item_one_primary", "item_one_secondary", "item_one_last");

    // define an explicit ordering that uses the result of a function over the supplied list
    Ordering o = Ordering.explicit("primary", "secondary", "last").onResultOf(new Function<String, String>() {

        // the function splits a values by '_' and uses the last element (primary, secondary etc.)
        public String apply(String input) {
            return Lists.newLinkedList(Splitter.on("_").split(input)).getLast();
        }

    });

    // the ordered result
    System.out.println("o.sortedCopy(list); = " + o.sortedCopy(list));

总是比编写自定义比较器要好。不错! - sjr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接