5

Let us say I have a list of points returned with a sort function:

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);

How do I make sorted(...) conditional based on a boolean flag (sortThePoints), something like the below

points.stream()
if(sortThePoints){
 .sorted((p1, p2)->p1.x.compareTo(p2.x)) 
}
.forEach(System.out::println);
Naman
  • 27,789
  • 26
  • 218
  • 353

4 Answers4

8

Stream.sorted(Comparator) makes a stable sort if the stream is ordered. In other words, if two elements are equals then they'll keep their initial ordering.

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);
Mạnh Quyết Nguyễn
  • 17,677
  • 1
  • 23
  • 51
  • In your solution ech element passes the sorting/comparator, regardless if sorting is enabled or not. Readability also is misleading a bit, since `sorted()` step is in place anyway (even if conditional identity-comparator could be without effect). – hc_dev Dec 23 '19 at 12:09
4

You can break the chain, using a variable:

Stream<Point> pointStream = points.stream();

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

pointsStream.forEach(System.out::println);
ernest_k
  • 44,416
  • 5
  • 53
  • 99
2

Just store the stream into a variable and then keep reassigning based on logic

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);
iam.Carrot
  • 4,976
  • 2
  • 24
  • 71
  • 1
    This solution expresses __very clear__, if sorting is performed or not. To have the condition check outside the stream __avoids unnecessary processing__. Thus its clean and efficient. – hc_dev Dec 23 '19 at 12:13
1

I think that you need this.

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;
}
seunggabi
  • 1,699
  • 12
  • 12