如何在Java 8中创建条件排序

5
假设我有一个用排序函数返回的点列表:
List<Point> points = new ArrayList<>(); 
points.add(new Point(3, 30)); 
points.add(new Point(1, 10)); 
points.add(new Point(2, 20));

points.stream() 
.sorted((p1, p2)->p1.x.compareTo(p2.x)) 
.forEach(System.out::println);

我该如何根据布尔标志(sortThePoints)使sorted(…)具有条件性,例如下面的示例?
points.stream()
if(sortThePoints){
 .sorted((p1, p2)->p1.x.compareTo(p2.x)) 
}
.forEach(System.out::println);

1
if(sortThePoints) Collections.sort(points, (p1, p2)->p1.x.compareTo(p2.x)) - rkosegi
sortThePoints是否会影响集合元素?如果是,则使用filter() - Vishwa Ratna
4个回答

9

Stream.sorted(Comparator) 方法可以对流进行排序,如果流本身已经有序,则它会进行 稳定排序。也就是说,如果两个元素相等,它们将保持其初始顺序。

static final Comparator<Point> identityComparator = (p1, p2) -> 0;

Comparator<Point> normalComparator = (p1, p2)->p1.x.compareTo(p2.x);

(or Comparator<Point> normalComparator = Comparator.comparing(p -> p.x))

points.stream()
.sorted(sortThePoints ? normalComparator : identityComparator)
.forEach(System.out::println);

在您的解决方案中,每个元素都会通过排序/比较器,无论是否启用排序。可读性也有点误导,因为sorted()步骤无论如何都是就地进行的(即使条件身份比较器可能没有效果)。 - hc_dev

5
您可以使用变量打破循环链:
Stream<Point> pointStream = points.stream();

if(sortThePoints) {
    pointsStream = pointsStream.sorted((p1, p2)->p1.x.compareTo(p2.x));
}

pointsStream.forEach(System.out::println);

2

只需将流存储到变量中,然后根据逻辑不断重新分配即可。

Stream<Point> points = Stream.of(new Point(3, 30, new Point(1, 10), new Point(2, 20)));

if (sortValues)
    points = points.sorted((p1, p2)->p1.x.compareTo(p2.x));

points.forEach(System.out::println);

1
这个解决方案表达得非常清楚,是否进行排序都能看出来。在流之外进行条件检查可以避免不必要的处理。因此它既干净又高效。 - hc_dev

1
我认为你需要这个。
class enum SortType {
    X, Y, REVERSE_X, REVERSE_Y
};


List<Point> points = new ArrayList<>(); 
points.add(new Point(3, 30)); 
points.add(new Point(1, 10)); 
points.add(new Point(2, 20));

Comparator<Point> comparatorX = (Point p1, Point p2) -> p1.getX().compareTo(p2.getX()); 
Comparator<Point> comparatorY = (Point p1, Point p2) -> p1.getY().compareTo(p2.getY()); 

SortType sortType = SortType.X
swich(sortType) {
    case X:
        Collections.sort(points, comparatorX); 
        break;
    case REVERSE_X:
        Collections.sort(points, comparatorX.reversed()); 
        break;
    case Y:
        Collections.sort(points, comparatorY); 
        break;
    case REVERSE_Y:
        Collections.sort(points, comparatorY.reversed()); 
        break;
    default:
        break;
}

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