Java - 对字符串列表进行排序,根据字符串的包含确定顺序

时间:2016-07-01 09:48:14

标签: java string list sorting javafx

示例:

我们的名单包含5个名字: Kevin,Hans,Fritz,Han Solo,Peter

我现在想把所有包含“汉”的名字放在最上面。

所以排序后的列表看起来像这样:

Hans,Han Solo,Kevin,Fritz,Peter

到目前为止我尝试过:

没什么,因为我不知道,但我已经用谷歌搜索,没有找到任何东西。

从列表中删除/添加项目不是一个选项,因为我在CheckListView(ControlsFX组件)中使用列表,其中每个项目都有一个可能会丢失的已检查状态。

4 个答案:

答案 0 :(得分:2)

只需使用Comparator并根据您的条件定义您自己的比较方法:

public static void main(String[] args) {
    List<String> names = Arrays.asList("Kevin,Hans,Fritz,Han Solo,Peter".split(","));

    Collections.sort(names, new Comparator<String>() {
        final String PREFIX = "Han";
        @Override
        public int compare(String a, String b) {
            if (a.contains(PREFIX) && b.contains(PREFIX)) return a.compareTo(b);
            if (a.contains(PREFIX) && !b.contains(PREFIX)) return -1;
            if (!a.contains(PREFIX) && b.contains(PREFIX)) return 1;
            return 0;
        }
    });

    for (String n : names) {
        System.out.println(n);
    }
}

输出(恕我办公Han Solo必须在Hans之前,因为spaces之前,但您可以轻松修改我建议的条件)

Han Solo
Hans
Kevin
Fritz
Peter

答案 1 :(得分:2)

在java 8中,您可以根据应用于元素的函数创建Comparators。还有一些方法可以反转比较器和链式比较器产生的顺序。

这允许使用子串作为主要排序标准并将String排序作为次要标准来相对简单地创建比较器。请注意,根据您的要求,可能不需要第二部分(.thenComparing(Comparator.naturalOrder())):

final String part = "Han";

Comparator<String> comparator = Comparator.<String, Boolean>comparing(s -> s.contains(part)).reversed()
        .thenComparing(Comparator.naturalOrder());

使用此Comparator对商品进行排序的结果是

Han Solo, Hans, Fritz, Kevin, Peter

答案 2 :(得分:0)

为此,您需要使用Comparator<String>

比较两个Strings时,可以调用name1name2,如果name1包含"Han",则返回-1表示name1 1}}应该先来。如果name2包含"Han",则您返回1,表示name2应该首先出现。否则,两个String都不包含"Han",因此您返回0,表示不应交换它们。 注意:这不会按字母顺序对包含"Han"的字符串进行排序,因为您未在要求中指定此字符串。

在Java 8中,这很简单:

List<String> names = Arrays.asList("Kevin", "Hans", "Fritz", "Han Solo", "Peter");

names.sort((name1, name2) ->
   name1.contains("Han") ? -1 :
   name2.contains("Han") ? 1  :
   0
);

System.out.println(names);

输出:

[Han Solo, Hans, Kevin, Fritz, Peter]

答案 3 :(得分:0)

您可以使用Comparator指定排序的工作方式。

这个解决方案确实只移动包含&#34; Han&#34;到列表的前面 - 同时保持这些元素之间的原始顺序(因为它在所需的输出中定义) - 并且不对不包含&#34; Han&#34; <的元素进行排序/ strong>正如问题所述:&#34;我现在希望拥有包含&#34; Han&#34;的所有名称。在顶部。&#34;

List<String> names = Arrays.asList("Kevin", "Hans", "Fritz", "Han Solo", "Peter"));

names.sort(getMoveToFrontComparator("Han"));

System.out.println(names);

...

private Comparator<String> getMoveToFrontComparator(String part) {
    return new Comparator<String>() {

        @Override
        public int compare(String o1, String o2) {
            boolean containsFirst = o1.contains(part);
            boolean containsSecond = o2.contains(part);

            // Match vs No-Match: Match has the priority
            if(containsFirst && !containsSecond)
                return -1;
            if(!containsFirst && containsSecond)
                return 1;

            // Match vs Match or No-Match vs No-Match: no sorting is needed
            return 0;
        }
    };
}

输出为:

[Hans, Han Solo, Kevin, Fritz, Peter]

注意:如果您想对&#34;匹配与匹配&#34;进行排序&#34;非匹配与非匹配&#34;例如,您可以将return 0;替换为return o1.compareTo(o2);