> 文档中心 > Java8中Stream流的常用方法

Java8中Stream流的常用方法


了解Stream

Java8中有两大最为重要的改变 第一个是Lambda表达式 另外一个则是Stream API(java.util.stream.*)
Stream是java8中处理集合的关键抽象概念 它可以指定你希望对集合进行的操作 可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API对集合进行操作,就类似于使用SQL执行的数据库查询。也可以使用StreamAPI来并执行操作 简而言之 Stream API提供了一种高效且易于使用的处理数据的方式

什么是Stream

流(Stream)是数据渠道 用于操作数据源(集合、数组等)所生成的元素序列。
注意

  1. Stream 自己不会存储元素
  2. Stream不会改变源对象 相反 他们会返回一个持有结果的新Stream
  3. Stream操作是延迟执行的 这意味着他们会等到需要结果的时候才执行

Stream流中常用中间操作的方法

filter(Predicate p)

filter方法 接收Lambda 从流中排除某些元素

public class StreamTest {    List<User> userList = new ArrayList<User>();    @Before    public void init(){ userList.add(new User("李四",20,89.00)); userList.add(new User("李五",32,23.00)); userList.add(new User("李流",21,43.00)); userList.add(new User("李房间",43,123.12)); userList.add(new User("发动",12,15.32)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00));    }    @Test    public void FilterTest(){ //filter获取条件满足的 返回一个新流 userList.stream().filter(u->u.getAge() > 18)  .forEach(System.out::println); //结果是/* User(name=李四, age=20, source=89.0) User(name=李五, age=32, source=23.0) User(name=李流, age=21, source=43.0) User(name=李房间, age=43, source=123.12) */    }}

distinct()

distinct方法 筛选 通过流所生成元素的hashCode() 和 equals() 去除重复元素

public class StreamTest {    List<User> userList = new ArrayList<User>();    @Before    public void init(){ userList.add(new User("李四",20,89.00)); userList.add(new User("李五",32,23.00)); userList.add(new User("李流",21,43.00)); userList.add(new User("李房间",43,123.12)); userList.add(new User("发动",12,15.32)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00));    }    @Test    public void distinctTest(){ //去重的条件是 通过hashcode和equals来判断的 userList.stream()  .skip(2)  .distinct()  .forEach(System.out::println);    }}

limit(long maxSize)

limit方法 截断流 使其元素不超过给定数量

public class StreamTest {    List<User> userList = new ArrayList<User>();    @Before    public void init(){ userList.add(new User("李四",20,89.00)); userList.add(new User("李五",32,23.00)); userList.add(new User("李流",21,43.00)); userList.add(new User("李房间",43,123.12)); userList.add(new User("发动",12,15.32)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00));    }    @Test    public void limitTest(){ //limit表示 只满足limit参数的 就会停止操作 返回一个新流 userList.stream().filter(u->u.getAge() >= 18)  .limit(3)  .forEach(System.out::println); //结果是 /*   User(name=李四, age=20, source=89.0)   User(name=李五, age=32, source=23.0)   User(name=李流, age=21, source=43.0)  */    }}

skip(long n)

skip方法跳过元素 返回一个扔掉了前n个元素的流 若流中元素不足n个 则返回一个空流 与limit(n) 互补

public class StreamTest {    List<User> userList = new ArrayList<User>();    @Before    public void init(){ userList.add(new User("李四",20,89.00)); userList.add(new User("李五",32,23.00)); userList.add(new User("李流",21,43.00)); userList.add(new User("李房间",43,123.12)); userList.add(new User("发动",12,15.32)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00));    }    @Test    public void skipTest(){ //skip 跳转skip参数中输入的个数 如果输入的个数超过数组长度 返回空流 userList.stream()  .filter(u->u.getAge() >= 18)  .skip(2)  .forEach(System.out::println); /*     结果是     User(name=李流, age=21, source=43.0)     User(name=李房间, age=43, source=123.12)     User(name=案例, age=18, source=30.0)  */    }}

map(Function f)

map方法 接收一个函数作为参数 该函数会被应用到每个元素上 并将
其映射成一个新的元素

/** * @author 顾晨 */public class StreamTest {    List<User> userList = new ArrayList<User>();    @Before    public void init(){ userList.add(new User("李四",20,89.00)); userList.add(new User("李五",32,23.00)); userList.add(new User("李流",21,43.00)); userList.add(new User("李房间",43,123.12)); userList.add(new User("发动",12,15.32)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00));    }    @Test    public void mapTest(){ //map 取出指定的值 本次案例是将对象中name取出存入新的流中 userList.stream().map(User::getName)  .forEach(System.out::println); /*     李四     李五     李流     李房间     发动     案例     案例     案例  */    }}    

flatMap(Function f)

flatMap方法接收一个函数作为参数 将流中的每个值都换成另一个流 然后把所有流连接成一个流

public class StreamTest {    @Test    public void flatMapTest(){      //flatMap 取出每一个字符      List<String>  list = Arrays.asList("aaa","bbb","ccc","ddd");      list.stream().flatMap(StreamTest::getCharacter).forEach(System.out::println);    }    public static Stream<Character> getCharacter(String str){ List<Character> list = new ArrayList<>(); for (char c : str.toCharArray()) {     list.add(c); } return list.stream();    }}

sorted()

sorted方法产生一个新流 其中按自然顺序排序

public class StreamTest {    @Test    public void sortedTest() { //sorted 自然排序 表示String的中的默认排序规则进行排序 List<String> list = Arrays.asList("cafdlk","ffff","aaa","bbb","ccc","ddd"); list.stream().sorted()  .forEach(System.out::println); /*  * 结果是     aaa     bbb     cafdlk     ccc     ddd     ffff  */    }}

sorted(Comparator comp)

sorted(Comparator comp)方法产生一个新流 其中按比较器顺序排序

public class StreamTest {    List<User> userList = new ArrayList<User>();    @Before    public void init(){ userList.add(new User("李四",20,89.00)); userList.add(new User("李五",32,23.00)); userList.add(new User("李流",21,43.00)); userList.add(new User("李房间",43,123.12)); userList.add(new User("发动",12,15.32)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00)); userList.add(new User("案例",18,30.00));    }    @Test    public void sortedParamsTest(){ //自定义排序规则 进行排序 如果年龄相等按照姓名排序 不相等按照年龄排序 userList.stream()  .sorted((u1,u2)->{     if(u1.getAge().equals(u2.getAge())) {  return u1.getName().compareTo(u2.getName());     }else{  return -u1.getAge().compareTo(u2.getAge());     }  }) .forEach(System.out::println); /*     结果是     User(name=李房间, age=43, source=123.12)     User(name=李五, age=32, source=23.0)     User(name=李流, age=21, source=43.0)     User(name=李四, age=20, source=89.0)     User(name=案例, age=18, source=30.0)     User(name=案例, age=18, source=30.0)     User(name=案例, age=18, source=30.0)     User(name=发动, age=12, source=15.32)  */    }}

Stream流中终止操作的常见方法

allMatch

allMatch检查是否匹配所有元素

public class StreamTest01 {    List<User> userList = new ArrayList<User>();    @Before    public void init(){ userList.add(new User("李四",20,89.00)); userList.add(new User("李五",32,23.00)); userList.add(new User("李流",21,43.00)); userList.add(new User("李房间",43,123.12)); userList.add(new User("发动",12,15.32)); userList.add(new User("案例",18,32.32));    }    @Test    public void test(){ //如果集合中所有的数据匹配该条件返回true 否则返回false boolean b1 = userList.stream()  .allMatch(u->u.getAge().equals(18)); System.out.println(b1); //false   }}

anyMatch

anyMatch检查是否至少匹配一个元素

public class StreamTest01 {    List<User> userList = new ArrayList<User>();    @Before    public void init(){ userList.add(new User("李四",20,89.00)); userList.add(new User("李五",32,23.00)); userList.add(new User("李流",21,43.00)); userList.add(new User("李房间",43,123.12)); userList.add(new User("发动",12,15.32)); userList.add(new User("案例",18,32.32));    }    @Test    public void test(){ //如果集合中只要有数据匹配该条件返回true 否则返回false boolean b2 = userList.stream()  .anyMatch(u->u.getAge().equals(18)); System.out.println(b2); //ture    } }      

noneMatch

noneMatch检查是否没有匹配所有元素

public class StreamTest01 {    List<User> userList = new ArrayList<User>();    @Before    public void init() { userList.add(new User("李四", 20, 89.00)); userList.add(new User("李五", 32, 23.00)); userList.add(new User("李流", 21, 43.00)); userList.add(new User("李房间", 43, 123.12)); userList.add(new User("发动", 12, 15.32)); userList.add(new User("案例", 18, 32.32));    }    @Test    public void test() { //查询元素是否有符合条件的 如果有返回false 没有返回true boolean b3 = userList.stream()  .noneMatch(u -> u.getAge().equals(18)); System.out.println(b3); //false    }}

findFirst

findFirst 返回第一个元素

public class StreamTest01 {    List<User> userList = new ArrayList<User>();    @Before    public void init() { userList.add(new User("李四", 20, 89.00)); userList.add(new User("李五", 32, 23.00)); userList.add(new User("李流", 21, 43.00)); userList.add(new User("李房间", 43, 123.12)); userList.add(new User("发动", 12, 15.32)); userList.add(new User("案例", 18, 32.32));    }    @Test    public void test() { //返回元素中第一个值 用容器类Optional存储 防止空指针 Optional<User> first = userList.stream()  .findFirst(); System.out.println(first.get()); //User(name=李四, age=20, source=89.0)    }}

findAny

返回当前流中的任意元素

public class StreamTest01 {    List<User> userList = new ArrayList<User>();    @Before    public void init() { userList.add(new User("李四", 20, 89.00)); userList.add(new User("李五", 32, 23.00)); userList.add(new User("李流", 21, 43.00)); userList.add(new User("李房间", 43, 123.12)); userList.add(new User("发动", 12, 15.32)); userList.add(new User("案例", 18, 32.32));    }    @Test    public void test() { //返回任意一个元素 这里使用并行流 Optional<User> any = userList.parallelStream()  .filter(e->e.getSource()<30.00)  .findAny(); System.out.println(any.get());    }}

count

count 返回流中元素的总个数

public class StreamTest01 {    List<User> userList = new ArrayList<User>();    @Before    public void init() { userList.add(new User("李四", 20, 89.00)); userList.add(new User("李五", 32, 23.00)); userList.add(new User("李流", 21, 43.00)); userList.add(new User("李房间", 43, 123.12)); userList.add(new User("发动", 12, 15.32)); userList.add(new User("案例", 18, 32.32));    }    @Test    public void test() { //返回元素中的总个数 long count = userList.stream()  .count(); System.out.println(count); //6    }}

max

max 返回流中最大值

public class StreamTest01 {    List<User> userList = new ArrayList<User>();    @Before    public void init() { userList.add(new User("李四", 20, 89.00)); userList.add(new User("李五", 32, 23.00)); userList.add(new User("李流", 21, 43.00)); userList.add(new User("李房间", 43, 123.12)); userList.add(new User("发动", 12, 15.32)); userList.add(new User("案例", 18, 32.32));    }    @Test    public void test() { //查询元素中最大成绩是多少 Optional<Double> max = userList.stream()  .map(User::getSource)  .max(Double::compare); System.out.println(max.get()); //123.12    }}

min

min返回流中最小值

public class StreamTest01 {    List<User> userList = new ArrayList<User>();    @Before    public void init() { userList.add(new User("李四", 20, 89.00)); userList.add(new User("李五", 32, 23.00)); userList.add(new User("李流", 21, 43.00)); userList.add(new User("李房间", 43, 123.12)); userList.add(new User("发动", 12, 15.32)); userList.add(new User("案例", 18, 32.32));    }    @Test    public void test() { //查询最低分数是多少 Optional<Double> min = userList.stream()  .map(User::getSource)  .min(Double::compare); System.out.println("min.get() = " + min.get()); //15.32    }}

植物大战僵尸