Stream是JDK8 API的新成员,它容许以声明性方式处理数据集合java
实际开发中,项目中多数数据源都来自于MySQL,Oracle等.但如今数据源能够更多了,有MongoDB,Redis等,而这些NoSQL的数据就须要Java层面去处理程序员
Stream和Collection集合的区别:Collection是一种静态的内存数据结构,而Stream是有关计算的.前者是主要面向内存,存储在内存中,后者主要是面向CPU,经过CPU实现计算编程
注意:
api
建立Stream数组
一个数据源(集合,数组等),获取一个流markdown
中间操做数据结构
一个中间操做链,对数据源的数据进行处理dom
终止操做ide
一旦执行终止操做,就执行中间操做链,并产生结果.以后,不会再被使用函数式编程
/** * @PROJECT_NAME: myTest * @DESCRIPTION: Stream的方法测试 * @USER: 罗龙达 * @DATE: 2021/2/21 2:33 */ public class streamTest { @Test public void createStream(){ List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "", "jk"); //1. 经过集合建立stream -- 返回一个顺序流 Stream<String> listStream = strings.stream(); //返回一个并行流 Stream<String> paraStream = strings.parallelStream(); //2. 经过数组建立stream IntStream arrStream = Arrays.stream(new int[]{1, 3, 45, 6, 877, 12}); //3. 经过Stream的of()方法 Stream<Integer> integerStream = Stream.of(1, 3, 5, 7, 9); //4. 建立无限流 Stream.iterate(0,t -> t+2).limit(10).forEach(System.out::println); //5. 生成 Stream.generate(Math::random).limit(10).forEach(System.out::println); } }
@Test public void InOperationTest() { List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd", "abc", "jk"); //1. 经过集合建立stream -- 返回一个顺序流 Stream<String> listStream = strings.stream(); System.out.println("-----------测试filter--------------"); /** * filter(Predicate predicate) -- 接收lambda,从流中排除某些元素 * 查询列表中不为null的元素 */ // listStream.filter(s -> !s.equals("")).forEach(System.out::println); System.out.println("--------------测试limit------------"); /** *limit(n) -- 截断流,使元素不超过给定数量 */ strings.stream().limit(3).forEach(System.out::println); System.out.println("-------------测试skip--------------"); /** *skip(n) -- 跳过元素,返回一个扔掉了前n个元素的流,若是流中元素不足n个,则返回一个空流 */ strings.stream().skip(3).forEach(System.out::println); System.out.println("------------测试distinct-----------"); /** *distinct() -- 筛选,经过流所产生元素的hashCode()和equals()去除重复元素 */ strings.stream().distinct().forEach(System.out::println); }
@Test public void mapTest(){ System.out.println("----------------将字符串转换成大写---------------"); List<String> strings = Arrays.asList("aaa", "bb", "cccc", "d","eeeee","ff"); /** * 接受一个函数做为参数,将元素转换成其余形式或提取信息,该函数会被应用到每一个元素上,并将其映射成一个新的元素 */ strings.stream().map(String::toUpperCase).forEach(System.out::println); System.out.println("------------字符串长度大于3的元素的大写-----------"); /** * 返回字符串长度大于3的元素的大写 */ strings.stream().filter(s -> s.length() >3).map(String::toUpperCase).forEach(System.out::println); /** * flatMap(Function f) -- 接收一个函数做为参数,将流中的每一个值都换成另外一个流,而后把全部流链接成一个流。 */ strings.stream().flatMap(streamTest::fromStringToStream).forEach(System.out::println); } //将字符串中的多个字符构成的集合转换为对应的流 public static Stream<Character> fromStringToStream(String s){ ArrayList<Character> list = new ArrayList<>(); for (char c : s.toCharArray()) { list.add(c); } return list.stream(); }
@Test public void sortTest() { List<Integer> list = Arrays.asList(23, 45, -12, 2, 7, 89, 5); System.out.println("----------从小到大排序测试---------"); list.stream().sorted().forEach(System.out::println); System.out.println("----------从大到小排序测试---------"); list.stream().sorted((i1, i2) -> i2 - i1).forEach(System.out::println); }
@Test public void termOperationTest(){ List<Integer> list = Arrays.asList(23, 45, -12, 2, 7, 89, 5); System.out.println("-----------allMatchTest-------------"); /** * allMatch(Predicate predicate) -- 检查是否匹配全部元素 */ boolean allMatch = list.stream().allMatch(integer -> integer > 0); System.out.println(allMatch); System.out.println("-----------anyMatchTest-------------"); /** * allMatch(Predicate predicate) -- 检查是否匹配全部元素 */ boolean anyMatch = list.stream().anyMatch(integer -> integer > 0); System.out.println(anyMatch); System.out.println("----------noneMatchTest-------------"); /** * noneMatch(Predicate predicate) -- 检查是否没有匹配的元素 */ boolean noneMatch = list.stream().noneMatch(integer -> integer > 0); System.out.println(noneMatch); System.out.println("----------findFirstTest-------------"); /** * findFirst() -- 返回流中第一个元素 */ Optional<Integer> first = list.stream().findFirst(); System.out.println(first); System.out.println("------------findAnyTest-------------"); /** * findAny() -- 返回流中任一元素 */ Optional<Integer> any = list.parallelStream().findAny(); System.out.println(any); System.out.println("--------------countTest-------------"); /** * count() -- 返回流中元素的总个数 */ long count = list.stream().filter(i -> i > 0).count(); System.out.println(count); System.out.println("------------max / min Test----------"); /** * max/min(Comparator comparator) -- 返回流中最大值 / 最小值 */ Optional<Integer> max = list.stream().max((i1, i2) -> i1 - i2); System.out.println("max = " + max); Optional<Integer> min = list.stream().min((i1, i2) -> i1 - i2); System.out.println("min = " + min); System.out.println("--------------forEachTest------------"); /** * forEach(Consumer c) -- 内部迭代 */ // list.stream().forEach(System.out::println); list.forEach(System.out::println); }
@Test public void reduceTest(){ List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); /** * reduce(T identity, BinaryOperator) -- 能够将流中元素反复结合起来,获得一个值 */ Integer reduce = list.stream().reduce(0, Integer::sum); System.out.println("reduce = " + reduce); /** * reduce(BinaryOperator) -- 能够将流中元素反复结合起来,获得一个值,返回optional */ Optional<Integer> reduce2 = list.stream().reduce(Integer::sum); Optional<Integer> reduce3 = list.stream().reduce((i1, i2) -> i1 + i2); System.out.println("reduce2 = " + reduce2); System.out.println("reduce3 = " + reduce3); }
@Test public void collectTest(){ List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); /** *collect(Collector c) 将流转换为其余形式.接受一个Collector接口的实现 * 查找大于4的数字,结果返回一个list / set */ List<Integer> collectList = list.stream().filter(i -> i > 4).collect(Collectors.toList()); collectList.forEach(System.out::println); Set<Integer> collectSet = list.stream().filter(i -> i > 4).collect(Collectors.toSet()); collectSet.forEach(System.out::println); }
到目前为止,臭名昭著的空指针异常是致使Java应用程序失败的最多见缘由.
之前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava经过使用检查空值的方式来防止代码污染,鼓励程序员写更干净的代码.受到Google Guava的启发,Optional类已经成为Java 8 类库的一部分
Optional
Optional类的Javadoc描述以下: 这是一个能够为null的容器对象.若是值存在在isPresent()方法会返回true,调用get()方法会返回该对象
# 1 建立Optional类对象的方法 - Optional.of(T t): 建立一个Optional实例,`t必须非空` - Optional.empty(): 建立一个空的Optional实例 - Optional.ofNullable(T t): t能够为null # 2 判断Optional容器中是否包含对象: - boolean isPresent(): 判断是否包含对象 - void ifPresent(Consumer consumer): 若是有值,就执行Consumer接口的实现代码,而且该值会做为参数传给它 # 3 获取Optional容器的对象 - T get(): 若是调用对象包含值,返回该值,不然抛异常 - T orElse(): 若是有值则将其返回,不然返回指定的other对象 - T orElseGet(Supplier other): 若是有值将其返回,不然返回由Supplier接口实现提供的对象 - T orElseThrow(Supplier exceptionSupplier): 若是有值则将其返回,不然抛出由Supplier接口实现提供的异常
public class Girl { public Girl() { } public Girl(String name) { this.name = name; } private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
public class Boy { private Girl girlFriend; private String name; public Boy() { } public Boy(Girl girlFriend, String name) { this.girlFriend = girlFriend; this.name = name; } public Girl getGirlFriend() { return girlFriend; } public void setGirlFriend(Girl girlFriend) { this.girlFriend = girlFriend; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
@Test public void OptionalTest(){ Girl girl = new Girl(); girl=null; Optional<Girl> optionalGirl = Optional.ofNullable(girl); System.out.println("optionalGirl = " + optionalGirl); } //原始的getName方法 public String getGirlName(Boy boy){ return boy.getGirlFriend().getName(); } //优化后的getName方法 public String getGirlNameAfterOptimizing(Boy boy){ Optional<Boy> boyOptional = Optional.ofNullable(boy); //此时boy1必定非空 Boy boy1 = boyOptional.orElse(new Boy(new Girl("杨幂"), "我")); Girl girlFriend = boy1.getGirlFriend(); Optional<Girl> girlFriend1 = Optional.ofNullable(girlFriend); //girlOption必定非空 Girl girlOptional = girlFriend1.orElse(new Girl("赵丽颖")); return "女友的名字 : " + girlOptional.getName(); } @Test public void testGetName(){ Boy boy = new Boy(); // boy = null; boy.setGirlFriend(null); // boy.setGirlFriend(new Girl("迪丽热巴")); System.out.println(getGirlNameAfterOptimizing(boy)); }