如何对集合进行排序以获取Java顶部/底部的默认值?

时间:2019-04-05 09:23:44

标签: java

给出一个String列表,有时我们不得不对所有项目进行排序,除了一些必须放在顶部或底部的项目之外,

List<String> profiles = Arrays.asList(new String[] {
        "Y-Profile", "X-Profile", "Default", "A-Profile", "B-Profile"
    });

List<String> sortedProfiles = profiles.stream().sorted((o1, o2)->o1.compareTo(o2)).
                                   collect(Collectors.toList());

具有默认字符串比较的当前输出如下,

sortedProfiles ==> [A-Profile, B-Profile, Default, X-Profile, Y-Profile]

所需的输出如下,由于列表大小是动态的,并且可能在一段时间内变大,因此在Java中没有太多迭代或过滤的乐观方法是什么

sortedProfiles ==> [Default, A-Profile, B-Profile, X-Profile, Y-Profile]

4 个答案:

答案 0 :(得分:5)

您需要实现一个比o1.compareTo(o2)更智能的比较器。您可能最终会遇到这样的事情(虽然不一定是最有效的):

final String defaultVal = "Default";
List<String> sortedProfiles = profiles.stream().sorted(
    (o1, o2) -> defaultVal.equals(o1) && defaultVal.equals(o2)
                ? 0
                : (defaultVal .equals(o1)
                   ? -1
                   : (defaultVal .equals(o2) ? 1 : o1.compareTo(o2)))
).collect(Collectors.toList());

答案 1 :(得分:1)

您可以通过在排序之前删除值"Default"并将其添加到输出列表中,然后再添加排序的值来实现此目的:

public class StackoverflowMain {

    public static void main(String[] args) {
        List<String> profiles = new ArrayList<String>();
        profiles.add("Y-Profile");
        profiles.add("Z-Profile");
        profiles.add("U-Profile");
        profiles.add("A-Profile");
        profiles.add("Default");
        profiles.add("G-Profile");
        profiles.add("B-Profile");
        // print the list once for comparison in the console
        System.out.println(profiles);

        // create a new list that is supposed to hold the sorted values
        List<String> sortedProfiles = new ArrayList<String>();
        // remove the value that will not be sorted "correctly"
        profiles.remove("Default");
        // add it as the first element to the list for the sorted values
        sortedProfiles.add("Default");
        // then add the naturally sorted origin (which has no "Default" anymore)
        sortedProfiles.addAll(profiles.stream()
                .sorted((termOne, termTwo) -> termOne.compareTo(termTwo))
                .collect(Collectors.toList()));
        // print the manipulated / sorted list for comparison in the console
        System.out.println(sortedProfiles);
    }
}

如果不确定配置文件列表中是否有"Default",请添加contains("Default")检查,如果不存在则进行常规排序。

答案 2 :(得分:1)

将您不想排序的项目放在另一个列表中(可能不止一个)。

List<String> profiles = Arrays
            .asList(new String[] { "Y-Profile", "X-Profile", "Default", "A-Profile", "B-Profile}" });

    List<String> itemsToIgnore = Stream.of("Default").collect(Collectors.toList());

对列表进行排序,而忽略ignoreList中的项目。 按首选顺序comsorted和ignoreStream

    List<String> defaultAtTop = Stream
            .concat(itemsToIgnore.stream(), profiles.stream().filter(s -> !itemsToIgnore.contains(s)).sorted())
            .collect(Collectors.toList());
    System.out.println(defaultAtTop);

    List<String> defaultAtBottom = Stream
            .concat(profiles.stream().filter(s -> !itemsToIgnore.contains(s)).sorted(), itemsToIgnore.stream())
            .collect(Collectors.toList());
    System.out.println(defaultAtBottom);

答案 3 :(得分:1)

我喜欢@Aleks G的答案,并希望使用BiFunction给出类似的答案,因为我正在以某种方式自己学习/实验功能接口。使用前请进行测试,因为我经验不足,因此不能保证在任何情况下都可以使用。

currentTarget