Sort a list of numbers with all 0's at the end of result

时间:2017-11-08 21:59:13

标签: java java-stream

I have the list of persons and if the list of Input is 3,0,2,7,0,8

I want the output to be 2,3,7,8,0,0

With the following code, i can sort only non zero numbers to get 2,3,7,8 as output.

sortedList = personList.stream()
                       .filter(Person -> Person.getAge()>0)
                       .sorted(Comparator.comparingInt(Person::getAge))
                       .collect(Collectors.toList());

zeroList=personList.stream()
                       .filter(Person -> Person.getAge()==0)
                       .collect(Collectors.toList());

sortedList.addAll(zeroList);

Can the above two statements be merged into a single statement?

5 个答案:

答案 0 :(得分:4)

您可以通过编写适当的比较器来确保零结束:

sortedList = personList.stream()
   .sorted((p1, p2) -> {
      int a = p1.getAge();
      int b = p2.getAge();
      if (a == 0 && b == 0) return 0;
      if (a == 0) return 1;
      if (b == 0) return -1;
      return Integer.compare(a, b);
   })
   .collect(Collectors.toList());

或稍微紧凑:

sortedList = personList.stream()
   .sorted((p1, p2) -> {
      int a = p1.getAge();
      int b = p2.getAge();
      return a == 0 || b == 0 ? Integer.compare(b, a) : Integer.compare(a, b);
   })
   .collect(Collectors.toList());

答案 1 :(得分:2)

将0放在排序末尾的一个简单方法是将它们视为比较器中的大值:

Min

答案 2 :(得分:1)

你想要的是一个轮换;当你只是按年龄排序时,当你认为结果列表是一个响铃时,元素的顺序是正确的,所以你只想在最后一个零年龄值之后开始列表:

┌───────────────────────────┐
└─ 0  0  2  3  7  8       <─┘
         2  3  7  8  0  0 
sortedList = personList.stream()
    .sorted(Comparator.comparingInt(Person::getAge))
    .collect(Collectors.toCollection(ArrayList::new));
Collections.rotate(sortedList, -(int)personList.stream().filter(p->p.getAge()==0).count());

或者,您可以在比较时旋转int值范围内的年龄值。这是有效的,因为我们可以排除负年龄,因此我们可以旋转数字,使零成为MAX_VALUE,而所有其他数字保持相对顺序。

sortedList = personList.stream()
    .sorted(Comparator.comparingInt(p -> p.getAge()-Integer.MIN_VALUE-1))
    .collect(Collectors.toList());

顺便说一句,这相当于

sortedList = personList.stream()
    .sorted((p1, p2) -> Integer.compareUnsigned(p1.getAge()-1, p2.getAge()-1))
    .collect(Collectors.toList());

了解解决方案需要了解two's complement

答案 3 :(得分:0)

您可以在构建列表之前连接两个流:

sortedList = Stream<Person>.concat(
   personList.stream().filter(Person -> Person.getAge()>0)
                      .sorted(Comparator.comparingInt(Person::getAge)),
   personList.stream().filter(Person -> Person.getAge()==0))
                      .collect(Collectors.toList());

答案 4 :(得分:-2)

You specified a filter .filter(Person -> Person.getAge()>0) that does not allow element `equals to 0

You need to change to : .filter(Person -> Person.getAge()>=0)

Then you need to specify a more complex comparator

sortedlist = personList.stream()
            .filter(Person -> Person.getAge() >= 0)
            .sorted((o1, o2) -> {
                if (o1.getAge() == 0 || o2.getAge() == 0) 
                    return Integer.compare(o2.getAge(), o1.getAge());
                return Integer.compare(o1.getAge(), o2.getAge());
            })
            .collect(Collectors.toList());
  • If one of the Person's age is 0 it'll compare in reverse way (0 will be the bigger numer => at the end)
  • if none of ages is 0 : classic comparison between Integers