美文网首页
第一章:为什么要关心Java8

第一章:为什么要关心Java8

作者: 杨殿生 | 来源:发表于2018-09-20 15:04 被阅读0次

给苹果按照重量排序

        Collections.sort(lists, new Comparator<Apple>() {
            @Override
            public int compare(Apple o1, Apple o2) {
                return o1.getWeight().compareTo(o2.getWeight());
            }

Java8的写法

 lists.sort(Comparator.comparing(Apple::getWeight));

Java8对硬件的影响

Java8之前程序都是单线程的,如果想使用多线程那么需要自行处理并发,虽然很Java提供了线程池和并发集合,但使用Java8会更容易实现多线程

并行与共享的可变数据
写代码时不能访问共享的可变数据,这些函数成为纯函数或无状态函数或无副作用函数

Stream API

Java8新的API提供了Stream,它支持许多处理数据的并行操作,从而可以避免使用synchronized

向方法传递代码技巧(方法引用,lambda表达式)

Java8之前使用匿名内部类实现行为参数化,Java8之后使用行为参数化(通过API传递代码)不需要创建匿名内部类

函数式编程
将代码传递给方法的功能,还让我们能够使用一整套新技巧

函数式编程的基石
1,没有共享的可变数据
2,将方法和函数传递给其他方法的能力

Java中的函数

程序执行期间不能传递叫二等公民(方法,类),能传递叫一等公民,java8将函数在运行时传递把他编程一等公民

        //筛选一个目录中隐藏的文件
        File[] hiddenFiles1 = new File(".").listFiles(new FileFilter() {
            @Override
            public boolean accept(File pathname) {
                return pathname.isHidden();
            }
        });
        //java8 写法
        File[] hiddenFiles2 = new File(".").listFiles(File::isHidden);

方法引用
java8使用 方法引用:: 语法(即吧这个方法最为值)
使用File::isHidden就创建了一个方法引用

lambda-匿名函数
比如(int a) -> x+1

筛选出绿色并且重量大于150克的苹果

//筛选绿色苹果
    public static List<Apple> filterGreenApples(List<Apple> inventory){
        List<Apple> result = new ArrayList<>();
        for (Apple apple:inventory){
            if ("green".equals(apple.getColor())){
                result.add(apple);
            }
        }
        return result;
    }

    //筛选重量超过150克苹果
    public static List<Apple> filterHeavyApples(List<Apple> inventory){
        List<Apple> result = new ArrayList<>();
        for (Apple apple:inventory){
            if (apple.getWeight() > 150){
                result.add(apple);
            }
        }
        return result;
    }

第一版写两个方法
可以看出很多代码都是重复的,变动部分只有if判断我们可以将这部分抽取出来

  public static boolean isGreenApple(Apple apple){
        return "green".equals(apple.getColor());
    }
    
    public static boolean isHeavyApple(Apple apple){
        return apple.getWeight() > 150;
    }
    
    public interface Predicate<T t>{
        boolean test(T t);
    }
    
    static List<Apple> filterApples(List<Apple> inventory,Predicate<Apple> p){
        List<Apple> result = new ArrayList<>();
        for (Apple apple:inventory){
            if (p.test(apple)){
                result.add(apple);
            }
        }
        return result;
    }

    public static void main(String[] args){
        filterApples(lists,StreamTest::isGreenApple);
        filterApples(lists,StreamTest::isHeavyApple);
    }

第二版
我们需要把变化的部分抽取出来,然后使用函数引用将变化的部分传递到函数中,这样就可以防止代码重复

 filterApples(lists,(Apple apple) -> "green".equals(apple.getColor()));
 filterApples(lists,(Apple apple) -> apple.getWeight() > 150);
 filterApples(lists,(Apple apple) -> apple.getWeight() < 150 || "brown".equals(apple.getColor()));

第三版
java8中我们可以直接使用lambda表达式

        //从一个列表中筛选金额较高的交易,然后按货币分组
        Map<Currency,List<Transaction>> transactionByCurrencies = new HashMap<>();
        for (Transaction transaction:transactions){
            if (transaction.getPrice() > 1000){
                Currency currency = transaction.getCurrency();
                List<Transaction> transactionForCurrency = transactionByCurrencies.get(currency);
                if (transactionForCurrency == null){
                    transactionForCurrency = new ArrayList<>();
                    transactionByCurrencies.put(currency,transactionForCurrency);
                }
                transactionForCurrency.add(transaction);
            }
        }

之前的写法很难一眼看出这些代码是做什么的,因为有好几个嵌套的控制流指令,下面我们使用流来解决这个问题

 Map<Currency,List<Transaction>> transactionByCurrencies2 = 
                transactions.stream()
                        .filter((Transaction transaction) -> transaction.getPrice() > 1000)
                        .collect(Collectors.groupingBy(Transaction::getCurrency));

Java8的实现非常简洁。
我们使用集合要自己去做迭代,for-each这种迭代是外部迭代,相反,有了Stream API根本就不用操心循环的事情。数据处理完全是在库里内部进行的。这种思想叫内部迭代
并且流可以更好的利用多个处理器并行处理任务

Collection是为了存储和访问数据,而Stream是对数据描述进行计算
将苹果筛选问题转化成流
顺序处理苹果筛选为题

        List<Apple> heavyApples = lists.stream()
                .filter((Apple apple) -> apple.getWeight() > 150)
                .collect(Collectors.toList());

并行处理苹果筛选问题

        List<Apple> heavyApple = lists.parallelStream()
                .filter((Apple apple) -> apple.getWeight() > 150)
                .collect(Collectors.toList());

为保证并行,函数式编程中主要的意思是,把函数作为一等值,并且含有第二层意思,即在执行元素之间无互动

接口中默认方法

一般是库设计师使用

Optional<T>

防止出现空指针异常

Java8的新特性

函数参数化
lambda表达式,匿名参数

默认方法
Optional
CompletableFuture

相关文章

  • 为什么要关心Java8

    Stream API java8提供了一个新的API,简称Stream。它支持多核处理器并行操作,很多思路来源于数...

  • 第一章:为什么要关心Java8

    给苹果按照重量排序 Java8的写法 Java8对硬件的影响 Java8之前程序都是单线程的,如果想使用多线程那么...

  • 第一章 为什么要关心Java8

    1、请记住语言生态系统的思想,以及语言面临的“要么改变,要么衰亡”的压力。虽然Java可能现在非常有活力,但你可以...

  • 一、为什么要关心Java8

    1.Java8让编程起来更容易 提供了更多的编程工具和概念,能以更快,更简洁,更易于维护的方式解决问题,比如: J...

  • Java8初探

    1、概述 1.1 为什么要学习java8 java8可以让我们编写更为简洁的代码 1.1.1 【示例1】lambd...

  • Java 8 学习笔记

    第一章 为什么要关心Java 8 使用Stream库来选择最佳低级执行机制可以避免使用Synchronized(同...

  • JDK8 新特性

    为什么要学Java8 Java8让你的编程变得更容易 充分稳定的利用计算机硬件资源 Lambda lambda 是...

  • 死磕 java并发包之LongAdder源码分析

    问题 (1)java8中为什么要新增LongAdder? (2)LongAdder的实现方式? (3)LongAd...

  • 死磕 java并发包之LongAdder源码分析

    题 (1)java8中为什么要新增LongAdder? (2)LongAdder的实现方式? (3)LongAdd...

  • 为什么要关心别人

    记得当时爱情公寓里曾小贤的心理医生,指出曾老师通过关心别人来关心自己,“你有病”。所以,生活中莫名地对别人关心,其...

网友评论

      本文标题:第一章:为什么要关心Java8

      本文链接:https://www.haomeiwen.com/subject/xsegnftx.html