Java Stream
在Java8中,可以使用lambda表达式实例化比较器(Comparator)。
还可以颠倒自然顺序和比较器(Comparator)提供的顺序。
自然排序使用Comparable提供的排序,该排序必须由实例为流元素的类实现。
在本页中,将使用java 8 Stream sorted()方法对列表List, Map和Set进行排序。

1、使用Stream sorted()完成自然排序、比较器和反向排序

下面是sorted()方法的语法

  • sorted():它使用自然顺序对流中的元素进行排序。元素类必须实现Comparable接口。
  • sorted(Comparator<? super T> comparator):这里使用lambda表达式创建一个Comparator实例。可以按升序和降序对流元素进行排序。

下面的代码行将按自然顺序对列表进行排序。

  1. list.stream().sorted()

要反转自然顺序,Comparator提供reverseOrder()方法。

  1. list.stream().sorted(Comparator.reverseOrder())

下面的代码行使用Comparator对列表进行排序。

  1. list.stream().sorted(Comparator.comparing(Student::getAge))

为了颠倒顺序,Comparator提供reversed()方法。

  1. list.stream().sorted(Comparator.comparing(Student::getAge).reversed())

2、在List中使用Stream sorted()方法

下面对Student列表进行排序操作。首先,将按自然顺序排序,然后使用比较器(Comparator)。
下面是颠倒自然排序和比较器提供的排序的例子。
SortList.java

  1. package com.concretepage;
  2. import java.util.ArrayList;
  3. import java.util.Comparator;
  4. import java.util.List;
  5. import java.util.stream.Collectors;
  6. public class SortList {
  7. public static void main(String[] args) {
  8. List<Student> list = new ArrayList<Student>();
  9. list.add(new Student(1, "Mahesh", 12));
  10. list.add(new Student(2, "Suresh", 15));
  11. list.add(new Student(3, "Nilesh", 10));
  12. System.out.println("---Natural Sorting by Name---");
  13. List<Student> slist = list.stream().sorted().collect(Collectors.toList());
  14. slist.forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));
  15. System.out.println("---Natural Sorting by Name in reverse order---");
  16. slist = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
  17. slist.forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));
  18. System.out.println("---Sorting using Comparator by Age---");
  19. slist = list.stream().sorted(Comparator.comparing(Student::getAge)).collect(Collectors.toList());
  20. slist.forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));
  21. System.out.println("---Sorting using Comparator by Age with reverse order---");
  22. slist = list.stream().sorted(Comparator.comparing(Student::getAge).reversed()).collect(Collectors.toList());
  23. slist.forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));
  24. }
  25. }

Student.java

  1. package com.concretepage;
  2. public class Student implements Comparable<Student> {
  3. private int id;
  4. private String name;
  5. private int age;
  6. public Student(int id, String name, int age) {
  7. this.id = id;
  8. this.name = name;
  9. this.age = age;
  10. }
  11. public int getId() {
  12. return id;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public int getAge() {
  18. return age;
  19. }
  20. @Override
  21. public int compareTo(Student ob) {
  22. return name.compareTo(ob.getName());
  23. }
  24. @Override
  25. public boolean equals(final Object obj) {
  26. if (obj == null) {
  27. return false;
  28. }
  29. final Student std = (Student) obj;
  30. if (this == std) {
  31. return true;
  32. } else {
  33. return (this.name.equals(std.name) && (this.age == std.age));
  34. }
  35. }
  36. @Override
  37. public int hashCode() {
  38. int hashno = 7;
  39. hashno = 13 * hashno + (name == null ? 0 : name.hashCode());
  40. return hashno;
  41. }
  42. }

输出

  1. ---Natural Sorting by Name---
  2. Id:1, Name: Mahesh, Age:12
  3. Id:3, Name: Nilesh, Age:10
  4. Id:2, Name: Suresh, Age:15
  5. ---Natural Sorting by Name in reverse order---
  6. Id:2, Name: Suresh, Age:15
  7. Id:3, Name: Nilesh, Age:10
  8. Id:1, Name: Mahesh, Age:12
  9. ---Sorting using Comparator by Age---
  10. Id:3, Name: Nilesh, Age:10
  11. Id:1, Name: Mahesh, Age:12
  12. Id:2, Name: Suresh, Age:15
  13. ---Sorting using Comparator by Age with reverse order---
  14. Id:2, Name: Suresh, Age:15
  15. Id:1, Name: Mahesh, Age:12
  16. Id:3, Name: Nilesh, Age:10

3、在Set中使用Stream sorted()方法

下面对Student类的集合(Set)进行排序操作,此类必须重写equals()hashCode()方法来标识唯一的元素。对于自然排序,学生类需要实现Comparable接口。
在下面的例子中,将使用自然排序和比较器提供的排序对集合进行排序。
SortSet.java

  1. package com.concretepage;
  2. import java.util.Comparator;
  3. import java.util.HashSet;
  4. import java.util.Set;
  5. public class SortSet {
  6. public static void main(String[] args) {
  7. Set<Student> set = new HashSet<Student>();
  8. set.add(new Student(1, "Mahesh", 12));
  9. set.add(new Student(2, "Suresh", 15));
  10. set.add(new Student(3, "Nilesh", 10));
  11. System.out.println("---Natural Sorting by Name---");
  12. set.stream().sorted().forEach(e -> System.out.println("Id:"
  13. + e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));
  14. System.out.println("---Natural Sorting by Name in reverse order---");
  15. set.stream().sorted(Comparator.reverseOrder()).forEach(e -> System.out.println("Id:"
  16. + e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));
  17. System.out.println("---Sorting using Comparator by Age---");
  18. set.stream().sorted(Comparator.comparing(Student::getAge))
  19. .forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));
  20. System.out.println("---Sorting using Comparator by Age in reverse order---");
  21. set.stream().sorted(Comparator.comparing(Student::getAge).reversed())
  22. .forEach(e -> System.out.println("Id:"+ e.getId()+", Name: "+e.getName()+", Age:"+e.getAge()));
  23. }
  24. }

输出

  1. ---Natural Sorting by Name---
  2. Id:1, Name: Mahesh, Age:12
  3. Id:3, Name: Nilesh, Age:10
  4. Id:2, Name: Suresh, Age:15
  5. ---Natural Sorting by Name in reverse order---
  6. Id:2, Name: Suresh, Age:15
  7. Id:3, Name: Nilesh, Age:10
  8. Id:1, Name: Mahesh, Age:12
  9. ---Sorting using Comparator by Age---
  10. Id:3, Name: Nilesh, Age:10
  11. Id:1, Name: Mahesh, Age:12
  12. Id:2, Name: Suresh, Age:15
  13. ---Sorting using Comparator by Age in reverse order---
  14. Id:2, Name: Suresh, Age:15
  15. Id:1, Name: Mahesh, Age:12
  16. Id:3, Name: Nilesh, Age:10

4、在Map中使用Stream sorted()方法

这里将按键和值对Map进行排序。
SortMap.java

  1. package com.concretepage;
  2. import java.util.Comparator;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. public class SortMap {
  6. public static void main(String[] args) {
  7. Map<Integer, String> map = new HashMap<>();
  8. map.put(15, "Mahesh");
  9. map.put(10, "Suresh");
  10. map.put(30, "Nilesh");
  11. System.out.println("---Sort by Map Value---");
  12. map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue))
  13. .forEach(e -> System.out.println("Key: "+ e.getKey() +", Value: "+ e.getValue()));
  14. System.out.println("---Sort by Map Key---");
  15. map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey))
  16. .forEach(e -> System.out.println("Key: "+ e.getKey() +", Value: "+ e.getValue()));
  17. }
  18. }

输出

  1. ---Sort by Map Value---
  2. Key: 15, Value: Mahesh
  3. Key: 30, Value: Nilesh
  4. Key: 10, Value: Suresh
  5. ---Sort by Map Key---
  6. Key: 10, Value: Suresh
  7. Key: 15, Value: Mahesh
  8. Key: 30, Value: Nilesh

下面要对值为自定义对象的Map进行排序。
SortMapOfCustomObject.java

  1. package com.concretepage;
  2. import java.util.Comparator;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. public class SortMapOfCustomObject {
  6. public static void main(String[] args) {
  7. Map<Integer, Student> map = new HashMap<>();
  8. map.put(1, new Student(1, "Mahesh", 12));
  9. map.put(2, new Student(2, "Suresh", 15));
  10. map.put(3, new Student(3, "Nilesh", 10));
  11. //Map Sorting by Value i.e student's natural ordering i.e by name
  12. map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue))
  13. .forEach(e -> {
  14. Integer key = (Integer)e.getKey();
  15. Student std = (Student)e.getValue();
  16. System.out.println("Key: " + key +", value: ("+ std.getId() +", "+ std.getName()+", "+ std.getAge()+")");
  17. });
  18. }
  19. }

输出

  1. Key: 1, value: (1, Mahesh, 12)
  2. Key: 3, value: (3, Nilesh, 10)
  3. Key: 2, value: (2, Suresh, 15)