在之前的工做中,业务中不少时候是须要循环来获取某一个列表中的一些数据,好比获取某一个值作业务逻辑的判断,或者获取其中一部分的数据,如使用状态的标志位等等,这个时候可能不少时候都是使用简单的for循环、Foreach循环或者迭代器等方式,不少时候为了处理业务都是须要循环嵌套循环的。可是在Java8中为集合的相关处理提供了一个更强大的工具,那么就是Stream,在浏览代码的时候看见了其余人的书写,感受很惊奇(此时本身也很无语,Java8出来这么久了,本身好像好没有意识到它到底添加了那些新的内容,有什么新的特性,简化了那些操做等等),因此本身就对这个东西充满了好奇。数组
它是Java8 API添加的一个新的抽象流,它把要处理的元素看作一种流,流在管道中传输,而且能够在管道的节点上进行处理,例如排序,筛选和聚合等操做,可让人以一种声明的方式来处理数据。
元素流在管道中通过中间操做(intermediate operation)处理,最后由最终操做(terminal operation)获得前面的处理结果。ide
+------------------------+ +---------+ +-----------+ +--------+ +-------+
| stream of elements +--------> |filter +-----> |sorted +-----> |map +----> |collect|
+-----------------------+ +---------+ +-----------+ +--------+ +-------+工具
stream是一个来自数据源的元素队列并支持聚合操做:
(1)元素是特定的元素,造成一个队列,可是stream不会存储元素,而是按需计算
(2)数据源能够是集合、数组、I/Ochannel等
(3)集合操做相似链式的SQL,如filter、map、reduce、find、match、sortde等this
使用stream方式,为集合建立串行流spa
使用parallelStream 为集合建立并行流code
Stream提供了新的方法来迭代流中的每个数据blog
public class StreamDemoTest { private final static Integer MAX_CIRCLE = 100; public static void main(String[] args) { List<Integer> strList = new ArrayList<>(); Map<Integer, String> integerMap = new HashMap<>(); for (int i = 0; i < MAX_CIRCLE; i++) { strList.add(i); integerMap.put(i, i+"e"); } strList.stream().forEach(s -> System.out.println(s)); } }
map方法用于映射每一个元素到对应的结果排序
public class StreamDemoTest { private final static Integer MAX_CIRCLE = 100; public static void main(String[] args) { List<Integer> strList = new ArrayList<>(); Map<Integer, String> integerMap = new HashMap<>(); for (int i = 0; i < MAX_CIRCLE; i++) { strList.add(i); integerMap.put(i, i+"e"); } //strList.stream().forEach(s -> System.out.println(s)); List<Integer> integerList = strList.stream().map(i -> i * i).collect(Collectors.toList()); integerList.stream().forEach(s -> System.out.println(s)); } }
filter用于经过设置的条件过滤出元素继承
List<String> stringList = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 long count = stringList.stream().filter(string ->string!="abc").count(); //获取不是abc和空的字符串 List<String> list = stringList.stream().filter(str -> str != "abc"&&str!="").collect(Collectors.toList());
用于获取指定数量的流队列
List<String> stringList = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 long count = stringList.stream().filter(string ->string!="abc").count(); //限定获取过滤条件后的数量 List<String> list = stringList.stream().filter(str -> str != "abc"&&str!="").limit(3).collect(Collectors.toList()); list.stream().forEach(s-> System.out.println(s));
limit的位置能够在filter前面或者后面,只是表示的含义不同而已。
sorted用于对流进行排序
public static void main(String[] args) { List<String> strList = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); //天然排序 System.out.println("天然排序"); strList.stream().sorted().forEach(s -> System.out.println(s)); System.out.println("倒序排序"); strList.stream().sorted(Comparator.reverseOrder()).forEach(s -> System.out.println(s)); }
输出结果已经按照要求进行了排序,默认的是升序排列了,若是想简单的倒序排序,可使用 Stream<T> sorted(Comparator<? super T> comparator)方法,里面采用Comparator.reverseOrder()进行倒序排序。
若是是自定义的其余的类型,怎么进行排序那?
下面是自定义的一个用户信息的简单实体
class User { /** * 姓名 **/ private String userName; /** * 英文名称 **/ private String englishName; /** * 年龄 **/ private int age; /** * 住址 **/ private String address; /** * 电话 **/ private String tel; public User(String userName, String englishName, int age) { this.userName = userName; this.englishName = englishName; this.age = age; } public User(String userName, String englishName, int age, String address, String tel) { this.userName = userName; this.englishName = englishName; this.age = age; this.address = address; this.tel = tel; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getEnglishName() { return englishName; } public void setEnglishName(String englishName) { this.englishName = englishName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } @Override public String toString() { return "User{" + "userName='" + userName + '\'' + ", englishName='" + englishName + '\'' + ", age=" + age + ", address='" + address + '\'' + ", tel='" + tel + '\'' + '}'; } }
public static void main(String[] args) { /* List<String> strList = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); //天然排序 System.out.println("天然排序"); strList.stream().sorted().forEach(s -> System.out.println(s)); System.out.println("倒序排序"); strList.stream().sorted(Comparator.reverseOrder()).forEach(s -> System.out.println(s));*/ List<User> userList = new ArrayList<>(); User user = new User("Angle", "B", 10); userList.add(user); user = new User("Heni", "G", 39); userList.add(user); user = new User("Eson", "F", 6); userList.add(user); user = new User("Cily", "D", 2); userList.add(user); user = new User("Cily", "G", 6); userList.add(user); user = new User("Eson", "G", 6); userList.add(user); System.out.println("正常输出"); userList.stream().forEach(s-> System.out.println(s.toString())); System.out.println("按照名称默认升序排列"); userList.stream().sorted(Comparator.comparing(User::getUserName)).forEach(s -> System.out.println(s)); System.out.println("按照名称进行倒序排列"); userList.stream().sorted(Comparator.comparing(User::getUserName).reversed()).forEach(s -> System.out.println(s)); System.out.println("多元素排列"); userList.stream().sorted(Comparator.comparing(User::getUserName).thenComparing(User::getAge).reversed()).forEach(s -> System.out.println(s)); System.out.println("转换为map"); userList.stream().collect(Collectors.toMap(User::getUserName,User::getAge,(newValue,oldValue)->newValue)).entrySet().stream().forEach(e-> { System.out.println(e.getKey()+"====="+e.getValue()); }); System.out.println("过滤之后的"); userList.stream().filter(e -> e.getUserName().equals("Eson")).sorted(Comparator.comparing(User::getAge).reversed()) .forEach(e -> System.out.println(e.getUserName() + "======" + e.getAge())); System.out.println("若是是重复的key,值转为list"); Map<String, List<String>> map = userList.stream().collect(Collectors.toMap(User::getUserName,p->{ List<String> ageList = new ArrayList<>(); ageList.add(p.getAge() + ""); return ageList; },(List<String> valueNew,List<String> valueOld)->{ valueNew.addAll(valueOld); return valueNew; })); map.entrySet().stream().forEach(e-> { System.out.println(e.getKey()+"====="+e.getValue()); }); }
输出结果:
正常输出 User{userName='Angle', englishName='B', age=10, address='null', tel='null'} User{userName='Heni', englishName='G', age=39, address='null', tel='null'} User{userName='Eson', englishName='F', age=6, address='null', tel='null'} User{userName='Cily', englishName='D', age=2, address='null', tel='null'} User{userName='Cily', englishName='G', age=6, address='null', tel='null'} 按照名称默认升序排列 User{userName='Angle', englishName='B', age=10, address='null', tel='null'} User{userName='Cily', englishName='D', age=2, address='null', tel='null'} User{userName='Cily', englishName='G', age=6, address='null', tel='null'} User{userName='Eson', englishName='F', age=6, address='null', tel='null'} User{userName='Heni', englishName='G', age=39, address='null', tel='null'} 按照名称进行倒序排列 User{userName='Heni', englishName='G', age=39, address='null', tel='null'} User{userName='Eson', englishName='F', age=6, address='null', tel='null'} User{userName='Cily', englishName='D', age=2, address='null', tel='null'} User{userName='Cily', englishName='G', age=6, address='null', tel='null'} User{userName='Angle', englishName='B', age=10, address='null', tel='null'} 多元素排列 User{userName='Heni', englishName='G', age=39, address='null', tel='null'} User{userName='Eson', englishName='F', age=6, address='null', tel='null'} User{userName='Cily', englishName='G', age=6, address='null', tel='null'} User{userName='Cily', englishName='D', age=2, address='null', tel='null'} User{userName='Angle', englishName='B', age=10, address='null', tel='null'}
能够看出来,整个排序是至关的简单了,不须要本身的类继承comparable,也不须要本身扩展排序comparator了。
对于map类型格式的数据。能够对键排序或者值排序
1 public static void main(String[] args) { 2 Map<String, String> map = new LinkedHashMap<String, String>(); 3 map.put("12", "ddd"); 4 map.put("23", "eee"); 5 map.put("34", "ddw"); 6 map.put("21", "ecc"); 7 8 System.out.println("根据值排序"); 9 map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue)).forEach(e -> { 10 String key = e.getKey(); 11 String value = e.getValue(); 12 System.out.println("键值"+key+"值"+value); 13 }); 14 System.out.println("根据键排序"); 15 map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getKey)).forEach(e -> { 16 //System.out.println(e.toString()); 17 String key = e.getKey(); 18 String value = e.getValue(); 19 System.out.println("键值"+key+"值"+value); 20 }); 21 }
输出的结果:
根据值排序
键值12值ddd
键值34值ddw
键值21值ecc
键值23值eee
根据键排序
键值12值ddd
键值21值ecc
键值23值eee
键值34值ddw
综合看下来,使用对应的Stream比使用日常简单的循环而言代码量少了不少。