Java 8 实战——第一章:为什么要关心 java 8

1.1 java怎么还在变

    物竞天择,适者生存

    1.1.1 Java 在编程语言生态系统中的位置

         java8 对于程序员的主要好处在于,他提供更多的编程工具和概念,能以更快,尤其是更简洁,更易于维护的方式解决新的或    者现有的编程问题。

        由于这些特性,他主要运用于对性能要求没那么高,但是对安全性,可维护性要求较高的场景。

   1.1.2 流处理

        流是一系列数据项,一次只能生成一项。程序可以从输入流一项一项读取数据项,然后再把数据项一项一项写入到输出流,一个程序的输出流和可能是另一个程序的输入流。

        Steam<T> 就是一个T类型项目,Steam API的很多方法可以连接起来形成一个流水线。

        这样做的好处在于

        ①:可以在更高的抽象层次上写java程序了,思路变成把一个流变成另外一个流,而不是一次只能处理一个项目。

        ②:java8 中可以一次将输入的几个不相关的部分拿到不同的CPU内核,分别执行你的Stream操作流水线。

   1.1.3 用行为参数化把代码传递给方法

        java8 增加了将方法(你的代码:方法或者函数)作为参数传递给另一个方法的能力,将其称之为行为参数化。Stream API就是构建在通过传递代码使操作行为实现参数化的思想上。当把compareUsingCustomerId传进去,你就把sort行为参数化了。

1.1.4 并行与共享的可变数据

      写代码时不能访问共享的可变数据,这些函数被称为“无状态函数”,“纯函数”,“无副作用函数”。

      前面说的并行,只有假定代码的多个副本可以独立的工作才能进行,但是要访问的是一个共享变量就行不通了。

      没有共享的可变数据将代码传递给其他方法的能力,这两个要点,是函数式编程范式的基石;

??

与此相反,在命令式编程
范式中,你写的程序则是一系列改变状态的指令。“不能有共享的可变数据”的要求意味着,一
个方法是可以通过它将参数值转换为结果的方式完全描述的;换句话说,它的行为就像一个数学
函数,没有可见的副作用

1.1.5 java需要演变

      语言需要不断的跟进硬件的更新和程序员的期待。

1.2 Java 中的函数

    编程语言的整个目的就是操作值。

    将二等公民(类,方法)转化为一等公民(值),在运行中传递方法,将方法转化为一等公民。

  1.2.1 方法和lambda 作为一等公民

        第一个新特性-方法引用:

        lambda-匿名函数:函数式编程风格,即为编写把函数作为一等值来传递的程序。

1.2.2 传递代码:一个例子

      代码示例:

    //方法编写
    //参与比较的方法
	public static boolean isGreenApple(Apple apple){
		return "green".equals(apple.getColor());
	}
	public static boolean isHeavyApple(Apple apple){
		return apple.getWeight()>150;
	}
                                                                 //谓词<操纵的类>
	public 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;
	}

    //调用
    	List<Apple> heavyApples2 = filterApples(inventory,FilteringApples::isHeavyApple);
		System.out.println(heavyApples2);
        List<Apple> greenApples2 = filterApples(inventory,FilteringApples::isGreenApple);
		System.out.println(greenApples2);

 1.2.3 从传递方法到 Lambda

       把方法作为值传递很方便,但是这种方法适用性太窄,写一堆太麻烦,所以引入匿名函数或者lambda。

代码示例:

List<Apple> greenApples3 = filterApples(inventory,(Apple a)->"green".equals(a.getColor()));
System.out.println(greenApples3);

List<Apple> heavyApples3 = filterApples(inventory,(Apple a)->a.getWeight()>150);
System.out.println(heavyApples3);

lambda 适用于短小的语句,当语句多于几行时改用类。

为了更好的利用并行,Stream登场。

1.3 流

    基于集合处理时的套路和晦涩: 化外部迭代------>内部迭代,Stream API 代替 Collection API

    基于集合难于利用多核:            Stream API 代替 Collection API

    这么做的原因:

                ①:有许多反复出现的数据处理模式,如上例和数据库查询语言里熟悉的操作,如果库里有这些会非常方便:根据标                           准筛选数据,提取数据,或给数据分组。

                ②:这些操作往往是并行化的,将一个任务分成多个部分,n个核负责n个部分,处理完之后再合并结果。

List<Apple> heavyApples =  
    inventory.parallelStream().filter((Apple a) -> a.getWeight() > 150) .collect(toList());
System.out.println(heavyApples);

??

1.4 默认方法

       default 关键字 可以实现接口中的默认方法,即当接口增添新方法时,实现类可不必实现接口中新增加的方法。

       例如:

           扩充List接口,为其添加sort()方法,实现类可直接调用默认方法而不用实现它。

        default void sort(Comparator <?super E> c){
        	Collections.sort(this,c);
        }

   1.5 来自函数式编程的其他好思想

           前面说过两个核心思想:

             ① 讲方法和lambda作为一等值

             ② 在没有可变共享变量的前提下,函数或者方法可以安全、有效的并行执行。

           Stream API 运用到了这两种思想

            还有其他思想:

               ① 避免使用null,使用更多的描述性数据类型代替null。

               ② (结构)模式匹配:以后章节会详细说明

猜你喜欢

转载自blog.csdn.net/Curry7895/article/details/82527259
今日推荐