Stream流和Lambda表达式的介绍 以及两者的配合应用

Stream流的介绍

概念:Stream流用来操作操作集合或数组,在JDK1.8 引入一套Stream API;

我们要使用Stream流分三个阶段

1.创建流
有四种方式来创建Stream流:集合中有一个方法 Arrays 中的静态方法 Stream中的静态方法 of()


        //方式1 集合中有一个方法 stream()
        List<Integer> list = Arrays.asList(10, 20, 30);
        Stream<Integer> stream = list.stream();

        //方式2 Arrays 中的静态方法,可以获取一个流
        Stream<Integer> stream1 = Arrays.stream(new Integer[]{100, 200, 300});

        //方式3 Stream中的静态方法 of()
        Stream<Integer> integerStream = Stream.of(30, 60, 90, 30);

另外还可以创建一个无限流

Stream.generate(() -> Math.random()).limit(5).forEach(System.out::println);

2.进行中间操作

一个中间操作链,对数据源的数据进行处理

  1. 筛选与切片

             filter(Predicate p) 过滤 接收 Lambda ,从流中排除某些元素。
             distinct() 去重,通过流所生成元素的 hashCode () 和 equals () 去除重复元素
             limit( long maxSize)截断流,使其元素不超过给定数量。
             skip( long n)跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit (n) 互补
    
  2. 映射

              map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
              flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流.
              sorted() 产生一个新流,其中按自然顺序排序 元素实现Compareble接口
              sorted(Comparator comp) 产生一个新流,其中按比较器顺序排序 传入一个比较
    

3.终止操作

               allMatch(Predicate p) 检查是否匹配所有元素 比如判断 所有员工的年龄都是17岁 如果有一个不是, 就返回false
               anyMatch(Predicate p) 检查是否至少匹配一个元素 比如判断是否有姓王的员工, 如果至少有一个就返回true
               noneMatch(Predicate p) 检查是否没有匹配所有元素 比如判断所有员工的工资都是否都是高于3000 如果有一个人低于3000 就返回false

Lambda表达式的介绍

概念:Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。

Lambda表达式的语法

         Lambda 表达式在Java 语言中引入了一个新的语法元素和操作符。这个操作符为 “ ->” , 该操作符被称为 Lambda 操作符或箭头操作符。它将 Lambda 分为两个部分:
        
         左侧: 指定了 Lambda 表达式需要的所有参数
         右侧: 指定了 Lambda 体,即 Lambda 表达式要执行的功能。

例如:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上述 Lambda 表达式中的参数类型都是由编译器推断得出的。 Lambda 表达式中无需指定类型,程序依然可以编译,这是因为 javac 根据程序的上下文,在后台推断出了参数的类型。

函数式接口

函数式接口的定义是: 只包含一个抽象方法的接口,称为函数式接口。

Java中提供的4大核心函数式接口

在这里插入图片描述

其他函数式接口

在这里插入图片描述 在这里插入图片描述

方法引用与构造器引用

方法的引用:

        方法引用:使用操作符 “ ::” 将方法名和对象或类的名字分隔开来。

如下三种主要使用情况:

        对象::实例方法
        类::静态方法
        类::实例方法

**构造器引用:**与函数式接口相结合,自动与函数式接口中方法兼容。可以把构造器引用赋值给定义的方法,与构造器参数列表要与接口中抽象方法的参数列表一致!

格式:

        ClassName::new

对于Lambda表达式的要求:我们能看懂Lambda表达式,在我们自己写的时候也可以用实现接口的方法去实现功能,无非就是代码看起来不够简介,并且我们的IDEA可以自动帮我们简写。

下面我们看一下例题将Stream流与Lambda表达式进行综合的运用

public class Trader {
		private String name;  //交易员的姓名
		private String city;    //交易员工作的城市
		


	public Trader(String name, String city) {
		this.name = name;
		this.city = city;
	}

	@Override
	public String toString() {
		return "Trader{" +
				"name='" + name + '\'' +
				", city='" + city + '\'' +
				'}';
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}
}

提供一个Trader的类
创建出一些交由员对象,添加到集合中,然后用StreamAPI 完成下面的问题

		Trader raoul = new Trader("Raoul", "Cambridge");
		Trader mario = new Trader("Mario", "Milan");
		Trader alan = new Trader("Alan", "Cambridge");
		Trader brian = new Trader("Brian", "Cambridge");
		
		transactions = Arrays.asList(
				new Transaction(brian, 2011, 300),
				new Transaction(raoul, 2012, 1000),
				new Transaction(raoul, 2011, 400),
				new Transaction(mario, 2012, 710),
				new Transaction(mario, 2012, 700),
				new Transaction(alan, 2012, 950)
		);

	1. 找出2011年发生的所有交易, 并按交易额排序(从低到高)
	2. 交易员都在哪些不同的城市工作过?
	3. 查找所有来自剑桥的交易员,并按姓名排序
	4. 返回所有交易员的姓名字符串,按字母顺序排序
	5. 有没有交易员是在米兰工作的?
	6. 打印生活在剑桥的交易员的所有交易额
	7. 所有交易中,最高的交易额是多少
	8. 找到交易额最小的交易	

由要求的我们需要先获得流并且对应开始讲到的中间操作对数据处理达到我们的要求

public class 作业 {


    public static void main(String[] args) {
        Trader raoul = new Trader("Raoul", "Cambridge");
        Trader mario = new Trader("Mario", "Milan");
        Trader alan = new Trader("Alan", "Cambridge");
        Trader brian = new Trader("Brian", "Cambridge");

        List<Transaction> transactions = Arrays.asList(
                new Transaction(brian, 2011, 300),
                new Transaction(raoul, 2012, 1000),
                new Transaction(raoul, 2011, 400),
                new Transaction(mario, 2012, 710),
                new Transaction(mario, 2012, 700),
                new Transaction(alan, 2012, 950)
        );
        Stream<Transaction> stream = transactions.stream();

        //1. 找出2011年发生的所有交易,并按交易额排序(从低到高)
//       stream.filter(e -> (e.getYear() == 2011)).sorted((o1, o2) -> o2.getValue()-o1.getValue()).forEach(System.out::println);


        //2. 交易员都在哪些不同的城市工作过?
        //stream.map(e -> e.getTrader().getCity()).distinct().forEach(System.out::println);

        //3. 查找所有来自剑桥的交易员,并按姓名排序
        stream.filter(e -> e.getTrader().getCity().equals("Cambridge")).sorted((x, y) -> (x.getTrader().getName().compareTo(y.getTrader().getName()))).map(e->e.getTrader()).distinct().forEach(System.out::println);
        //4. 返回所有交易员的姓名字符串,按字母顺序排序
       //stream.map(e->e.getTrader().getName()).distinct().sorted(String::compareTo).forEach(System.out::println);
        //5. 有没有交易员是在米兰工作的?
//        boolean milan = stream.anyMatch(e -> e.getTrader().getCity().equals("Milan"));
//        System.out.println(milan);
        //6. 打印生活在剑桥的交易员的所有交易额
        //Integer cambridge = stream.filter(e -> e.getTrader().getCity().equals("Cambridge")).map(e -> e.getValue()).reduce(0, (x, y) -> x + y);
        //System.out.println(cambridge);
        //7. 所有交易中,最高的交易额是多少
//               Optional<Integer> max = stream.map(Transaction::getValue).max(new Comparator<Integer>() {
//            @Override
//            public int compare(Integer o1, Integer o2) {
//                return o1 - o2;
//            }
//        });
//        Integer integer = max.get();
//        System.out.println(integer);


        //8. 找到交易额最小的交易
//        Transaction transaction = stream.min((o1, o2) -> o1.getValue() - o2.getValue()).get();
//        System.out.println(transaction);
       // System.out.println(stream.max((x, y) -> x.getValue() - y.getValue()).get());
    }

}

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值