java8流式操作

系列文章目录

第一章 万事万物皆对象
第二章 java构造器
第三章 java访问权限
第四章 java初始化
第五章 java继承
第六章 java重载与重写
第七章 java接口和抽象类
第八章 java数组
第九章 java内部类
第十章 java时间操作
第十一章 final关键字
第十二章 java字符串
第十三章 java异常
第十四章 java泛型
第十五章 java IO操作
第十六章 java NIO操作
第十七章 java zip压缩
第十八章 java反射
第十九章 java反射之Type接口
第二十章 java8流式操作
第二十一章 java8函数式编程



原文链接 https://zhhll.icu/2020/java基础/java8/1.java Stream操作/

java stream操作

Stream是什么

Stream又称为流,可以将集合转换为一种流,对集合中的每个元素进行一系列的流式操作,流并不存储元素,对流的操作也不会修改数据源

数据源 ------转换为–》流----》进行中间操作----》终止操作

多个中间操作可以连接起来形成一个流水线,除非流水线触发终止操作,否则中间操作不会执行任何处理,在终止操作时一次性全部处理

转化为流

使用stream()或者parallelStream()方法将集合转为流

生成流

可以使用Stream.generate来生成流,产生一个无限流,通过反复调用函数来生成流

Stream<String> stream = Stream.generate(()->"Echo");

也可以使用Stream.of来生成Stream,产生一个给定值的流

Stream<String> stream1 = Stream.of("hello", "java8");

可以用Stream.empty生成一个不包含任何元素的流

Stream<Object> empty = Stream.empty();

可以使用Arrays.stream根据数据来生成流

Stream<String> stream2 = Arrays.stream(new String[]{"hello", "java8"});

中间操作

筛选
filter

过滤操作,只返回为true(满足Predicate断言条件)的数据

// filter方法接收的是Predicate
Stream<T> filter(Predicate<? super T> predicate);
/**
* filter  接收lambda,从流中排除某些元素
*/
public static void testFilter(){
  // 中间操作
  // 使用的Predicate   boolean test(T t);
  Stream<String> stream = list.stream()
    .filter(e ->
            {
              System.out.println("filter中间操作");
              return e.equals("张三");
            }
           );
  // 这时中间操作还没有执行执行
  System.out.println("----中间操作结束----");
  //终止操作:一次执行全部操作
  stream.forEach(
    System.out::println
  );
}
distinct

去重

/**
* distinct 筛选,通过流所生成元素的hashCode()和equals()方法去重
*/
public static void testDistinct(){
  list.stream().distinct().forEach(System.out::println);
}
切片
limit

返回前n个元素

/**
* limit 截断流,使其元素不超过给定数量
*/
public static void testLimit(){
  list.stream().limit(2).forEach(System.out::println);
}
skip

去除(跳过)前n个元素

/**
* skip 跳过元素,返回一个扔掉了前n个元素的流。若流中元素不足n个,则返回空流
*/
public static void testSkip(){
  list.stream().skip(2).forEach(System.out::println);
}
public static void testLimitAndSkip(){
  System.out.println("--------先limit再skip---------");
  list.stream().limit(2).skip(1).forEach(System.out::println);
  System.out.println("--------先skip再limit---------");
  list.stream().skip(1).limit(2).forEach(System.out::println);
}

注意:在limit和skip搭配使用的时候,两个的顺序不同会导致结果不同

  • 先进行limit,再进行skip时,会选择前两个数据,然后再跳过第一个数据,只会筛选出一条数据
  • 先进行skip,再进行limit时,会先跳过一条数据,在选择剩下数据的前两条,最终会筛选出两条数据
排序
sorted

排序可以有两种排序方式,第一种是进行排序的类要实现Comparable接口,第二种是在自己实现一个Comparator接口

 /**
 * sorted()自然排序  Comparable 所要排序的类必须实现Comparable接口
 */
public static void test(){
  list.stream().map(User::getAge).sorted().forEach(System.out::println);
}

/**
* sorted(Comparator com) 定制排序(Comparator)
*/
public static void test1(){
  list.stream().sorted(
    (o1, o2) -> {
      if(o1.getAge() > o2.getAge()){
        return -1;
      }
      return 0;
    }
  ).forEach(System.out::println);
}
映射
map

转换功能,将mapper应用于当前流中的所有元素所产生的结果

// map方法接收的参数为Function接口
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
/**
* map 接收lambda,将元素转换为其他形式或提取信息。接收一个函数作为函数,
* 该函数会被应用到每个元素上,并将其映射成一个新的元素
*
* 如果函数返回的是一个流的话,使用map会使得流里存储着多个流
*/
public static void testMap(){
  // 使用Function  R apply(T t);
  list.stream().map(User::getAge).forEach(System.out::println);
}
flatmap

将多个Stream合并成一个Stream,将mapper应用于当前流中所有元素所产生的结果连接到一起(每一个结果都是一个流)

// flatMap方法接收的参数为Function接口
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
/**
* flatMap  接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
*
* 如果函数返回的是一个流,使用flatMap会使得函数返回的流中的元素放到一个流中
*/
public static void testFlatMap(){
  // 要求Function  R apply(T t);中返回值是一个Stream流
  List<String> add = new ArrayList<>();
  add.add("添加元素");
  List<String> strings = list.stream().map(User::getName).collect(Collectors.toList());
  strings.stream().flatMap(
    TestStreamApi1::joinStream
  ).forEach(System.out::println);
}

终止操作

allMatch

流中所有元素都要匹配给定的条件为true,否则为false 相当于且

/**
* allMatch测试
*/
public static void testAllMatch(){
  boolean isSex = list.stream().allMatch(
    l -> l.getSex() == 0
  );
  System.out.println(isSex);
}
anyMatch

流中有任意一条数据匹配给定的条件为true,否则为false 相当于并

/**
* anyMatch测试
*/
public static void testAnyMatch(){
  boolean isSex = list.stream().anyMatch(
    l -> l.getSex() == 0
  );
  System.out.println(isSex);
}
noneMatch

流中所有的数据都不匹配给定条件时为true,否则为false 相当于非

/**
* noneMatch测试
*/
public static void testNoneMatch(){
  boolean isSex = list.stream().noneMatch(
    l -> l.getSex() == 0
  );
  System.out.println(isSex);
}
findFirst

找到第一个元素

/**
* findFirst测试
*/
public static void testFindFirst(){
  User user = list.stream().sorted(
    ((o1, o2) -> {
      if(o1.getAge() > o2.getAge()){
        return -1;
      } else if(o1.getAge() < o2.getAge()){
        return 1;
      }
      return 0;
    })
  ).findFirst().get();
  System.out.println(user);
}
findAny

找到其中任意一个元素

/**
* findAny测试
*/
public static void testFindAny(){
  User user = list.stream().filter(
    l -> l.getSex() == 0
  ).findAny().get();
  System.out.println(user);
}
count

返回流中元素的数量

/**
* count测试
*/
public static void testCount(){
  long count = list.stream().count();
  System.out.println(count);
}
max

返回流中根据比较之后的最大值元素

// max方法接收的是Comparator接口
Optional<T> max(Comparator<? super T> comparator);
/**
* max测试
*/
public static void testMax(){
  User user = list.stream().max(
    ((o1, o2) -> {
      if(o1.getAge() > o2.getAge()){
        return 1;
      } else if(o1.getAge() < o2.getAge()){
        return -1;
      }
      return 0;
    })
  ).get();
  System.out.println(user);
}
min

返回流中根据比较之后的最小值元素

// min方法接收的是Comparator接口
Optional<T> min(Comparator<? super T> comparator);
/**
* min测试
*/
public static void testMin(){
  User user = list.stream().min(
    ((o1, o2) -> {
      if(o1.getAge() > o2.getAge()){
        return 1;
      } else if(o1.getAge() < o2.getAge()){
        return -1;
      }
      return 0;
    })
  ).get();
  System.out.println(user);
}

归约和收集

归约reduce

使用reduce来进行运算,从一组值中生成一个值

// reduce方法接收的是BinaryOperator接口(二元运算操作)  
Optional<T> reduce(BinaryOperator<T> accumulator);
/**
* 归约  将流中元素反复结合起来,得到一个值
* reduce(T identity, BinaryOperator<T> accumulator) /BinaryOperator<T> accumulator/U identity,
*                  BiFunction<U, ? super T, U> accumulator,
*                  BinaryOperator<U> combiner
*/
public static void testReduce(){
  List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9);
  // BinaryOperator  二元运算   R apply(T t, U u);
  int sum = list.stream().reduce((x, y) -> x+y).get();
  System.out.println(sum);
}
收集collect

根据不同的收集器collect(Collectors.toList())、collect(Collectors.toSet())来返回不同的集合

/**
* 收集 collect -- 将流转换为其他形式 接收一个Collector接口的实现,用于给Stream中元素做汇总的方法
*/
public static void testCollect(){
  // Collector是一个接口  有一个Collectors提供了各种转换方式
  List<String> strings = list.stream().map(User::getName).collect(Collectors.toList());
  System.out.println(strings);
}
Optional的使用

当初java8打着去除空指针的旗号推出了Optional,但是很多人用起来发现其实和判断是否为null没什么区别

其实有效地使用Optional的关键是要使用这样的方法:它的值不存在的情况下产生一个可替代物,而只有在值存在的情况下才会使用这个值

// 提供一个默认值,在Optional为空的时候使用默认值
public T orElse(T other)
// 提供一个默认值,在Optional为空的时候使用默认值(调用other来产生默认值)
public T orElseGet(Supplier<? extends T> other)
// 提供一个默认值,在Optional为空的时候抛出异常(调用exceptionSupplier来产生异常)
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
// 如果Optional不为空,将值传给consumer
public void ifPresent(Consumer<? super T> consumer)
// 产生该Optional的值传递给mapper后的结果,只要这个Optional不为空且结果不为null,否则产生一个空Optional
public<U> Optional<U> map(Function<? super T, ? extends U> mapper)

而对于有些人总是使用optional.isPresent()来判断是不是空,其实和之前判断value != null没什么区别,这种情况使用Optional没有任何好处

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拾光师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值