bpe*_*ira 15 java sorting java-8 java-stream
我有一个对象列表,我想按属性的字母顺序对其进行排序。但是,如果此属性匹配特定的字符串,我想添加一个例外规则。例如:
public class Car {
String name;
}
Run Code Online (Sandbox Code Playgroud)
List<Car> cars = asList(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars
.stream
.sorted(Comparator.comparing(Car::getName))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
如果那样的cars.name == "Unassigned"话,这辆车应该保持在列表的末端,其结果将是:
[Car<Honda>, Car<Nissan>, Car<Yamaha>, Car<Unassigned>]
Run Code Online (Sandbox Code Playgroud)
Eug*_*ene 15
List<Car> sortedCars = cars
.stream()
.sorted(Comparator.comparing(
Car::getName,
Comparator.comparing((String x) -> x.equals("Unassigned"))
.thenComparing(Comparator.naturalOrder())))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
这里发生了很多事情。首先我正在使用Comparator.comparing(Function, Comparator); 然后(String x) -> x.equals("Unassigned")实际比较一个Boolean(即Comparable);然后使用的事实(String x)-作为这种类型的见证人,可以正确地推断类型...
最直接,最易读的解决方案可能是编写一个实现您的排序逻辑的自定义比较器。
但是,您仍然可以使用该Comparator.comparing方法使它变得更加prittier:
public static final String UNASSIGNED = "Unassigned";
List<Car> cars = List.of(
new Car("Unassigned"),
new Car("Nissan"),
new Car("Yamaha"),
new Car("Honda"));
List<Car> sortedCars = cars.stream()
.sorted(Comparator.comparing(Car::getName, (name1, name2) -> {
if (name1.equals(name2)) return 0;
if (name1.equals(UNASSIGNED)) return 1;
if (name2.equals(UNASSIGNED)) return -1;
return name1.compareTo(name2);
}))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
另外,将命名常量用于特殊值(例如your)是一种很好的样式"Unassigned"。
另外,请注意,如果您不需要保留未排序的cars列表,则可以对该列表进行排序而不是使用流:
cars.sort(UNASSIGNED_COMPARATOR);
Run Code Online (Sandbox Code Playgroud)