Comparator comparing java stream

Java Stream Sort — Comparator with 2 or more Criteria for Objects

Issue: I am trying to check if I can sort the list (ArrayList of data type Object), using 2 or more criteria’s. Please note I am aware of using Comparator with thenComparing feature. I wish to check if there is a way to sort with 2 or more criteria w/o having to use a custom data type where I can easily use Comparator feature. For 1 criteria sorting, the below code works. In this case if I do the below, the IntelliJ IDE immediately gives a error saying — ‘Cannot resolve method ‘get(int)’ for o.get(3)

.sorted(Comparator.comparing(o -> o.get(3).toString()).thenComparing(. ) 

I have also referred to many threads in this forum sample — Link1 Link2 Code (This works well for single criteria)

List> listOutput = new ArrayList<>(); . . listOutput = listOutput .stream() .sorted(Comparator.comparing(o -> o.get(3).toString())) .collect(Collectors.toList()); 

Added (Details of Object) (Note) String dataType — exchange, broker,segment, coCode LocalDate dataType — tradeDate LocalTime dataType — tradeTime double dataType — sellPrice, buyPrice

List lineOutput = new ArrayList<>(); lineOutput.add(exchange); lineOutput.add(broker); lineOutput.add(segment); lineOutput.add(tradeDate); // Entry Date lineOutput.add(tradeTime); // Entry Time lineOutput.add(coCode); lineOutput.add(sellPrice - buyPrice); // Profit / Loss listOutput.add(lineOutput); // Add line to Output 

Источник

Sorting a list with stream.sorted() in Java

Am I missing something? The list is not sorted afterward. It should sort the lists according to the item with the lowest value.

public static void print(List list, int i)

9 Answers 9

This is not like Collections.sort() where the parameter reference gets sorted. In this case you just get a sorted stream that you need to collect and assign to another variable eventually:

List result = list.stream().sorted((o1, o2)->o1.getItem().getValue(). compareTo(o2.getItem().getValue())). collect(Collectors.toList()); 

You’ve just missed to assign the result

list.sort((o1, o2) -> o1.getItem().getValue().compareTo(o2.getItem().getValue())); 

and make it more succinct using Comparator.comparing :

list.sort(Comparator.comparing(o -> o.getItem().getValue())); 

After either of these, list itself will be sorted.

Your issue is that list.stream.sorted returns the sorted data, it doesn’t sort in place as you’re expecting.

@Pwnstar This isn’t processing a list of Item s, it’s processing a list of objects with an Item field. I’m not aware of a way in Java to do a nested method reference, e.g. MyObject::getItem::getValue . Lmk if there is such way, but otherwise the above boilerplate is required.

Java 8 provides different utility api methods to help us sort the streams better.

If your list is a list of Integers(or Double, Long, String etc.,) then you can simply sort the list with default comparators provided by java.

List integerList = Arrays.asList(1, 4, 3, 4, 5); 

Creating comparator on fly:

integerList.stream().sorted((i1, i2) -> i1.compareTo(i2)).forEach(System.out::println); 

With default comparator provided by java 8 when no argument passed to sorted():

integerList.stream().sorted().forEach(System.out::println); //Natural order 

If you want to sort the same list in reverse order:

 integerList.stream().sorted(Comparator.reverseOrder()).forEach(System.out::println); // Reverse Order 

If your list is a list of user defined objects, then:

List personList = Arrays.asList(new Person(1000, "First", 25, 30000), new Person(2000, "Second", 30, 45000), new Person(3000, "Third", 35, 25000)); 

Creating comparator on fly:

personList.stream().sorted((p1, p2) -> ((Long)p1.getPersonId()).compareTo(p2.getPersonId())) .forEach(person -> System.out.println(person.getName())); 

Using Comparator.comparingLong() method(We have comparingDouble(), comparingInt() methods too):

personList.stream().sorted(Comparator.comparingLong(Person::getPersonId)).forEach(person -> System.out.println(person.getName())); 

Using Comparator.comparing() method(Generic method which compares based on the getter method provided):

personList.stream().sorted(Comparator.comparing(Person::getPersonId)).forEach(person -> System.out.println(person.getName())); 

We can do chaining too using thenComparing() method:

personList.stream().sorted(Comparator.comparing(Person::getPersonId).thenComparing(Person::getAge)).forEach(person -> System.out.println(person.getName())); //Sorting by person id and then by age. 

Person class

public class Person < private long personId; private String name; private int age; private double salary; public long getPersonId() < return personId; >public void setPersonId(long personId) < this.personId = personId; >public Person(long personId, String name, int age, double salary) < this.personId = personId; this.name = name; this.age = age; this.salary = salary; >public String getName() < return name; >public void setName(String name) < this.name = name; >public int getAge() < return age; >public void setAge(int age) < this.age = age; >public double getSalary() < return salary; >public void setSalary(double salary) < this.salary = salary; >> 

I feel like this answer is way too detailed for the question, and yet doesn’t address the question at all. Consider using this answer in a self-answered Q/A instead.

I also feel that this is the best and correct answer. using Comparator.comparing* is the way better and more JDK8 oriented approach

@River welcome to Java, it’s terrible. It would just make way too much sense to use «>» and »

It seems to be working fine:

List list = Arrays.asList(new BigDecimal("24.455"), new BigDecimal("23.455"), new BigDecimal("28.455"), new BigDecimal("20.455")); System.out.println("Unsorted list: " + list); final List sortedList = list.stream().sorted((o1, o2) -> o1.compareTo(o2)).collect(Collectors.toList()); System.out.println("Sorted list: " + sortedList); 

Example Input/Output

Unsorted list: [24.455, 23.455, 28.455, 20.455] Sorted list: [20.455, 23.455, 24.455, 28.455] 

Are you sure you are not verifying list instead of sortedList [in above example] i.e. you are storing the result of stream() in a new List object and verifying that object?

sorting Integer using streamAPI

arr.stream() .sorted((item1,item2)-> Integer.compare(item1.price, item2.price)) .forEach(item-> item.show()); //asc System.out.println("--------------------"); //desc arr.stream() .sorted((item1,item2)-> item1.priceitem.show()); 
List result = list .stream() .sorted(Comparator.comparing(Type::getValue)) .collect(Collectors.toList()); 
List result = list .stream() .sorted(Comparator.comparing(Type::getValue)) .toList(); 
List citiesName = Arrays.asList( "Delhi","Mumbai","Chennai","Banglore","Kolkata"); System.out.println("Cities : "+citiesName); List sortedByName = citiesName.stream() .sorted((s1,s2)->s2.compareTo(s1)) .collect(Collectors.toList()); System.out.println("Sorted by Name : "+ sortedByName); 

It may be possible that your IDE is not getting the jdk 1.8 or upper version to compile the code.

Set the Java version 1.8 for Your_Project > properties > Project Facets > Java version 1.8

This might help for people ending up here searching how to sort list alphabetically.

import lombok.Getter; import lombok.Setter; import lombok.ToString; import java.util.ArrayList; import java.util.Comparator; import java.util.List; public class SortService < public static void main(String[] args) < Listtest = new ArrayList<>(); test.add(prepareTestData("Asmin",1)); test.add(prepareTestData("saurav",4)); test.add(prepareTestData("asmin",2)); test.add(prepareTestData("Saurav",3)); test.forEach(data-> System.out.println(data)); /** Output * TestData(name=Asmin, * TestData(name=saurav, * TestData(name=asmin, * TestData(name=Saurav, */ test.sort(Comparator.comparing(TestData::getName,String::compareToIgnoreCase)); test.forEach(data-> System.out.println(data)); /**Sorted Output * TestData(name=Asmin, * TestData(name=asmin, * TestData(name=saurav, * TestData(name=Saurav, */ > private static TestData prepareTestData(String name, int id) < TestData testData= new TestData(); testData.setId(id); testData.setName(name); return testData; >> @Getter @Setter @ToString class TestData

Источник

Java Streams Comparators with Examples

Hi all, in this article, we will learn Java Streams Comparators like Comparator.comparing(), Comparator.naturalOrder(), Comparator.reverseOrder(), etc. The Comparator Interface provides us comparison and sorting options that we can use with Java Streams. Let’s start to do some examples and learn these tricks.

Java Streams Comparators with Examples

We will start with Sorting with Comparator examples then we will see Comparator.comparing() examples.

Sorting with Comparator Natural Order and Reverse Order

Let’s start with some sorting examples. We can use the Comparator interface’s naturalOrder() and reverseOrder() method to sort the elements of a stream in Ascending and Descending order.

@TestMethodOrder(MethodOrderer.OrderAnnotation.class) public class StreamSorted < Listnumbers = new ArrayList<>(); @BeforeEach public void setup(TestInfo testInfo) < System.out.println("Test name: " + testInfo.getDisplayName()); numbers.add(5); numbers.add(8); numbers.add(3); numbers.add(7); numbers.add(2); numbers.add(6); numbers.add(1); numbers.add(10); numbers.add(9); numbers.add(4); >@AfterEach public void tearDown() < numbers.clear(); System.out.println(""); >/** * Natural sort is Ascending Sort */ @Test @Order(1) public void streamNaturalOrderSortTest() < numbers.stream() .peek(number ->System.out.println("Filter operation for number: " + number)) //Peek is used for debugging purposes. .filter(number -> number % 2 == 1) //Filter the odd numbers .sorted(Comparator.naturalOrder()) //Natural order of sorting. (Ascending Sort) .limit(4) //After 4th element stop the stream. Process first 4 element. .peek(number -> System.out.println("Map operation for number: " + number)) //Peek is used for debugging purposes. .map(number -> number * 2) //Transform the number to number*2 .forEach(number -> System.out.println("Result of stream: " + number)); //Print the results. > /** * Reverse sort is Descending Sort */ @Test @Order(2) public void streamReverseOrderSortTest() < numbers.stream() .peek(number ->System.out.println("Filter operation for number: " + number)) //Peek is used for debugging purposes. .filter(number -> number % 2 == 1) //Filter the odd numbers .sorted(Comparator.reverseOrder()) //Reverse order of sorting. (Descending Sort) .limit(4) //After 4th element stop the stream. Process first 4 element. .peek(number -> System.out.println("Map operation for number: " + number)) //Peek is used for debugging purposes. .map(number -> number * 2) //Transform the number to number*2 .forEach(number -> System.out.println("Result of stream: " + number)); //Print the results. > >

Outputs

NaturalOrder Test Output

The test code:

  • Prints the debugging texts with peek().
  • Filters the odd numbers.
  • Then, sorts all elements with Natural Order which is Ascending Order.
  • With limit(4), when the 4th odd number is filtered which is “1”, it does not continue to do operations for other elements.
  • Prints the debugging texts with peek(),
  • Transform the elements to (elements*2).
  • Prints the results with forEach().

java stream comparator example

ReverseOrder Test Output

The test code:

  • Prints the debugging texts with peek().
  • Filters the odd numbers.
  • Then, sorts all elements with Reverse Order which is Descending Order.
  • With limit(4), when the 4th odd number is filtered which is “1”, it does not continue to do operations for other elements.
  • Prints the debugging texts with peek(),
  • Transform the elements to (elements*2).
  • Prints the results with forEach().

sort with comparator in java

Java Streams Comparator.comparing() Examples

The Comparator Interface provides us several comparisons and sorting options as seen below screenshot. We have already learned the reverseOrder() and naturalOrder() sorting with the Comparator Interface.

java comparator interface

Now, let’s do some examples with Comparator.comparing(). We have a Footballer class which contains the footballer’s name, team, and age. We can do comparisons on each element of the footballers by using comparator.comparing() method. We can find the footballer who has minimum age or the footballer who has maximum age etc.

Footballer Class

I used Lombok library’s Getter, Setter, and AllArgConstructor annotations to construct the Footballer class.

@Setter @Getter @AllArgsConstructor public class Footballer < String name; String team; int age; @Override public String toString() < return "Footballerpublic class ComparatorExamples < Listfootballers = new ArrayList<>(); @BeforeEach public void setup() < Footballer ronaldo = new Footballer("Ronaldo", "Manchester United", 36); Footballer messi = new Footballer("Messi", "Paris Saint German", 33); Footballer ozil = new Footballer("Ozil", "Fenerbahce", 32); footballers.add(ronaldo); footballers.add(messi); footballers.add(ozil); >/** * Comparator.comparing example */ @Test public void comparatorComparingTest() < OptionalyoungestFootballer = footballers.stream() .min(Comparator.comparing(Footballer::getAge)); Optional eldestFootballer = footballers.stream() .max(Comparator.comparing(Footballer::getAge)); youngestFootballer.ifPresent(footballer -> System.out.println("Youngest Footballer: " + footballer)); eldestFootballer.ifPresent(footballer -> System.out.println("Eldest Footballer: " + footballer)); > >

As you see below, by using Comparator.comparing() inside Stream’s min() and max() methods, we can easily find the youngest and eldest football players. Min and max method’s return type is Optional that’s why I wrapped the Footballer class with Optional. I will explain Optional class details in another article. Simply, it will help us not to get null pointer exceptions in Java.

comparator.comparing example

GitHub Project

In this article, I shared with you the most common usages of the Comparator Interface in Java. I hope you enjoyed reading it. See you in the next articles.

Thanks for reading,
Onur Baskirt

Onur Baskirt is a Software Engineering Leader with international experience in world-class companies. Now, he is a Software Engineering Lead at Emirates Airlines in Dubai.

Источник

Читайте также:  Самые популярные среды разработки python
Оцените статью