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); 
2
  • 1
    if(sortThePoints) Collections.sort(points, (p1, p2)->p1.x.compareTo(p2.x)) Commented Dec 23, 2019 at 10:52
  • Is sortThePoints affects the collection elements?? If yes then use filter(); Commented Dec 23, 2019 at 10:58

4 Answers 4

11

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); 
Sign up to request clarification or add additional context in comments.

1 Comment

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).
6

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

Comments

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

1 Comment

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.
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; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.