Java8中Stream流的常用方法
了解Stream
Java8中有两大最为重要的改变 第一个是Lambda表达式 另外一个则是Stream API(java.util.stream.*)
Stream是java8中处理集合的关键抽象概念 它可以指定你希望对集合进行的操作 可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API对集合进行操作,就类似于使用SQL执行的数据库查询。也可以使用StreamAPI来并执行操作 简而言之 Stream API提供了一种高效且易于使用的处理数据的方式
什么是Stream
流(Stream)是数据渠道 用于操作数据源(集合、数组等)所生成的元素序列。
注意
- Stream 自己不会存储元素
- Stream不会改变源对象 相反 他们会返回一个持有结果的新Stream
- 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 }}