Java8实战

Java8新特性

  1. 首先Java8引入了两个编程概念,一个是流处理,指的是程序可以从输入流中一个一个读取数据项,然后以同样的方式将数据项写入输出流。基于这种思想添加了Stream API。另一个引入的编程概念是通过API传递代码,也就是用行为参数化这种思想将代码传递给方法,比如我们将代码块作为参数传递给一个方法,稍后再去执行它,那么这个方法的行为就基于那块代码被参数化了。Java8之前处理集合时,我们得自己去做迭代的过程,也就是用for-each循环一个个来迭代元素,然后处理元素,我们把这种迭代方法称为外部迭代。而Java8有了Stream API后,数据处理完全在库内部进行,我们就不用操心循环的事了,这种思想叫做内部迭代,它相比原先处理集合的方式,会更清晰和简洁。StreamAPI处理集合还有一个优点:以前我们通过多线程代码来利用并行,也就是通过Java中的Thread API来编写多线程代码,但这并不是一个简单的事,因为线程可能会同时访问并更新共享变量,如果没有协调同步好,就会出现问题,传统上是利用Synchronized关键字来解决。而Stream可以更好的方便我们利用CPU资源进行并行的处理。(parallelStream)
  2. Lambda表达式:可以传递匿名函数,它没有名称,但有参数列表,函数主体,返回类型,可能还有可抛出的异常列表。它可以作为参数传递给方法或存储在变量中,而无需像匿名类那样写很多模板代码。它的写法结构是 参数 + 箭头 + Lambda主体。

1. 行为参数化

  指把一个行为(代码块)作为参数传入另一个方法。
  代码实现步骤是:先创建一个接口,接口中有且仅有一个抽象方法,然后实现这个接口,建立不同的行为,接着将行为当做参数传入 filter 方法中,这种做法类似于策略设计模式。

import java.util.ArrayList;
import java.util.List;

public class sss {
    public interface Predicate<T> {
        boolean test(T t);
    }

    private static <T> List<T> filter(List<T> list, Predicate<T> p) {
        List<T> result = new ArrayList<>();
        for (T e : list) {
            if (p.test(e)) {
                result.add(e);
            }
        }
        return result;
    }

    private List<Apple> list = new ArrayList<>();
    List<Apple> redApples = filter(list, (Apple apple) -> "red".equals(apple.getColor()));

    private List<Integer> numbers = new ArrayList<>();
    List<Integer> even = filter(numbers, (Integer i) -> i % 2 == 0);
}

2. Lambda

  • Lambda表达式由 参数、箭头、主体 组成

  • 在哪里可以使用Lambda?:可以在函数式接口上使用Lambda表达式,函数式接口就是只定义一个抽象方法的接口。

细节

  • (String s) -> “beijing”
  • (String s) -> { return “beijing”; }
  • 函数式接口的概念:只定义了一个抽象方法的接口(比如 Comparator)(可以有默认方法)
  • 目标引用 ::方法名称。比如 Apple::getWeight,表示引用Apple类中定义的getWeight方法,不需要括号,因为没有实际调用这个方法。它是 (Apple a) -> a.getWeight() 的快捷写法。
  • List.forEach(System.out::println); 输出集合中的每一个元素
  • 在这里插入图片描述
    在这里插入图片描述

7.1号 《Java8函数式编程》

  • 对于foreach循环里的函数式编程,可以将foreach替换为 flatmap

for循环版本:

        public Set<String> findLongTracks(List<Album> albums) {
            Set<String> trackNames = new HashSet<>();
            for (Album album : albums) {
                for (Track track : album.getTrackList()) {
                    if (track.getLength() > 60) {
                        String name = track.getName();
                        trackNames.add(name);
                    }
                }
            }
            return trackNames;
        }

函数式编程版本:

        public Set<String> test(List<Album> albums) {
            return albums.stream()
                    .flatMap(e -> e.getTracks())
                    .filter(t -> t.getLength() > 60)
                    .map(n -> n.getName())
                    .collect(toSet());
        }
  • 使用并行流时,forEach方法不能保证元素是按顺序处理的,可以使用 forEachOrdered 方法来实现。
并发和并行
  • 并发:两个任务共享时间段,比如一个程序要运行两个任务,并且只有一个CPU给他们分配了不同的时间片,那么这就是并发,而不是并行。
  • 并行:两个任务在同一时间发生,比如运行在多核CPU上。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值