Stream

Lambda 表达式

可以对某些匿名内部类的写法进行简化,让我们不用关注是什么对象,而是更关注我们对数据进行了什么操作。

核心原则:可推导可省略

基本格式:(参数列表)-> {代码}

关注的是参数列表和具体的逻辑代码体

省略规则:

  1. 参数类型可以省略

  2. 方法体中只有一句代码时大括号return和唯一一句代码的分号可以省略

  3. 方法只有一个参数时小括号可以省略

  4. 如果能简化成lambda 有快捷键:光标放在匿名内部类上面 Alt+回车(最简化的)

public static void main(String[] args) {
    //匿名内部类
    Num(new IntBinaryOperator() {
        @Override
         public int applyAsInt(int left, int right) {
             return left + right;
         }
     });
     //lambda表达式
     Num(( i,j) ->//参数类型可以省略
        i + j //方法体中只有一句代码时,大括号return和唯一一句代码的分号可以省略
     );
}
/**
 * 例子1
 */
public static int Num(IntBinaryOperator operator){
    int a = 20;
    int b = 30;
    return operator.applyAsInt(a,b);
}

Stream流

Java 8的stream使用的是函数式编程模式,可以被用来对集合或数组进行链状流式的操作,可以更方便的让我们对集合或数组进行操作。

注意事项:

  • 惰性求职(如果没有终结操作,中间操作是不会执行的)

  • 流是一次性的(一旦一个流对象经过一个终结操作之后。这个流就不能再被使用)

  • 不会影响原始数据(我们在流中可以对数据做很多处理。但是正常情况下是不会影响原来集合中的元素的。)

常用操作:

1.创建流

1.1单列集合

//单例集合  集合对象.stream()
List<Book> list = new ArrayList<>();
Stream<Book> stream = list.stream();

1.2数组

//数组:Arrays.stream(数组)或者Stream.of(数组)
Integer[] arr = {1,2,3};
Stream<Integer> stream1 = Arrays.stream(arr);
Stream<Integer> stream2 = Stream.of(arr);

1.3双列集合

//双列集合:转换成单列后在创建
Map<String,Object> map = new HashMap<>();
map.put("aaa",11);
//entrySet():装换成Set集合
Set<Map.Entry<String, Object>> set = map.entrySet();
Stream<Map.Entry<String, Object>> stream3 = set.stream();

2.中间操作

2.1 filter

可以对流中元素进行条件过滤,符合条件的才能继续留在流中

//查询集合中名字长度大于2的名字
stream.filter(book -> book.getName().length()>=2)
        .forEach(book -> System.out.println(book.getName()));

2.2 map

可以对流中元素进行计算或转换

//把集合中的所有分数+10
stream.map(book -> book.getScore())
        .map(s->s+10)
        .forEach(s-> System.out.println(s));

2.3 distinct

可以去除流中的重复元素

注意:distinct方法是依赖Object的equals方法判断是否是相同对象的。所以需要注意重写equals方法。(实体类添加 @EqualsAndHashCode 注解)

//查询集合中的名字,要求不能重复(整个对象的所有值相同才算重复,就单独名字相同不算重复)
list.stream()
        .distinct()
        .forEach(book-> System.out.println(book.getName()));

2.4 sorted

可以对流中的元素进行排序

如果调用空参的sorted()方法,实体类要实现Comparable类

//想要有比较能力  比如排序 就要实现Comparable类
public class Book implements Comparable<Book>
@Override
public int compareTo(Book o) {
    //改变这两个的位置可以调整降序还是升序
    return o.getScore()- this.getScore();
}
//根据分数降序排序,要求不能有重复的元素
list.stream()
        .distinct()
        //调用无参方法
        .sorted()
        .forEach(book-> System.out.println(book.getScore()));
//匿名内部类方法可直接使用
.sorted(new Comparator<Book>() {
    @Override
    public int compare(Book o1, Book o2) {
        return o1.getScore()- o2.getScore();
    }
})

2.5 limit

可以设置流的最大长度,超出的部分将被舍弃

//根据分数降序排序,要求不能有重复的元素,输出分数最高的两个
list.stream()
        .distinct()
        .sorted()
        .limit(2)
        .forEach(book-> System.out.println(book.getScore()));

2.6 skip

可以跳过流中的前n个元素,返回剩下的元素

//根据分数降序排序,要求不能有重复的元素,分数最高的不要输出
list.stream()
        .distinct()
        .sorted()
        .skip(1)
        .forEach(book-> System.out.println(book.getName()));

2.7 flatMap

map操作只能把一个对象转换成另一个对象来作为流当中的元素,而flatMap操作可以把一个对象转换成多个对象作为流中的元素。

//打印所有书籍的名字,对重复的元素进行去重(有多个作家,每个作家又有多本书)
authorList.stream()
        .flatMap(author -> author.getBooks().stream())
        .distinct()
        .forEach(book -> System.out.println(book.getName()));
//打印所有书籍的分类,对分类进行去重,不能出现这种格式(历史,散文)
getAuthors().stream()
        .flatMap(author -> author.getBooks().stream())
        .distinct()
        //book.getCategory().split(","):逗号分隔的字符串数组
        //数组转换成stream流 Arrays.stream(arr)或者Stream.of(arr)
        .flatMap(book -> Stream.of(book.getCategory().split(",")))
        .distinct()
        .forEach(s-> System.out.println(s));

3.终结操作(必须有终结操作,流才会被使用)

3.1 foreach

对流中元素进行遍历操作,我们通过传入的参数去指定对遍历的元素进行什么具体操作。

//输出所有作家的名字
getAuthors().stream()
        .forEach(author -> System.out.println(author.getName()));

3.2 count

可以用来获取当前流中元素的个数

注意:count会返回一个Long类型的结果,所以要接收一下才能输出。

//输出所有作家所出版的书籍数目,删除重复元素
long count = getAuthors().stream()
        .flatMap(author -> author.getBooks().stream())
        .distinct()
        .count();
System.out.println(count);

3.3 max&min

可以获取流中的最值

//输出所有作家所出版的书籍中得最高分和最低分
Optional<Integer> min = getAuthors().stream()
        .flatMap(author -> author.getBooks().stream())
        .map(book -> book.getScore())
        .min((o1, o2) -> o1 - o2);
//终结操作之后就不能在.了
Optional<Integer> max = getAuthors().stream()
        .flatMap(author -> author.getBooks().stream())
        .map(book -> book.getScore())
        .max((o1, o2) -> o1 - o2);
System.out.println("最小:"+min.get()+"   最大:"+max.get());

3.4 collect

可以把当前流转换成一个集合

//获取一个存放所有记者名字的 List集合
List<String> list = getAuthors().stream()
        .map(author -> author.getName())
        .collect(Collectors.toList());
System.out.println(list);
//获取一个存放所有书籍名字的 Set集合
Set<String> set = getAuthors().stream()
        .flatMap(author -> author.getBooks().stream())
        .map(book -> book.getName())
        .collect(Collectors.toSet());
System.out.println(set);
//获取一个Map集合,key为作者名字,values为List<books>
Map<String, List<Book>> map = getAuthors().stream()
        .distinct()
        .collect(Collectors.toMap(author -> author.getName(), author -> author.getBooks()));

3.5 查找和匹配

3.5.1 anyMatch

可以用来判断流中是否有任意符合匹配条件的元素,结果为boolean类型。

元素有一个满足即可。

//判断是否有年龄在29岁以上的作家
boolean b = getAuthors().stream()
        .anyMatch(author -> author.getAge() > 29);
System.out.println(b);

3.5.2 allMath

可以用来判断流中是否都符合匹配条件,结果为boolean类型,都符合返回t反之返回f。

必须所有元素都满足。

//判断是否所有作家都是成年人
boolean b = getAuthors().stream()
        .allMatch(author -> author.getAge() < 18);
System.out.println(b);

3.5.3 noneMatch

可以用来判断流中是否都不符合匹配条件,结果为boolean类型,都不符合返回t反之返回f。

必须所有元素都不满足。

//判断是否所有作家都没有100岁的
boolean b = getAuthors().stream()
        .noneMatch(author -> author.getAge() > 100);
System.out.println(b);

3.5.4 findAny

获取流中的任意一个元素,该方法没有办法保证获取的一定是流中的第一个元素。

//输出一个年龄小于50的作家姓名
Optional<Author> any = getAuthors().stream()
        .filter(author -> author.getAge() < 50)
        .findAny();
System.out.println(any.get().getName());

3.5.5 findFirst

获取流中的第一个元素

//输出年龄最小的作家姓名
Optional<Author> first = getAuthors().stream()
        .sorted((o1, o2) -> o1.getAge() - o2.getAge())
        .findFirst();
System.out.println("年龄最小的是"+first.get().getName());

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

这里是阿昂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值