java8 基础知识

为什么关注java8

Java 8所做的改变,在许多方面比Java历史上任何一次改变都深远。

  1. 简化编程
  • 列表排序

java8之前

Collections.sort(inventory, new Comparator() {
public int compare(Apple a1, Apple a2){
return a1.getWeight().compareTo(a2.getWeight());
}
});

java8

inventory.sort(comparing(Apple::getWeight));
它念起来就是“给库存排序,比较苹果的重量”。
2. 并行
STREAM API
java 8提供了一个新的API(称为“流”,Stream),它支持许多处理数据的并行操作,其思路和在数据库查询语言中的思路类似——用更高级的方式表达想要的东西,而由“实现”(在这里是Streams库)来选择最佳低级执行机制。这样就可以避免用 synchronized 编写代码,这一代码不仅容易出错,而且在多核CPU上执行所需的成本也比你想象的要高。
3. 行为参数化
行为参数化就是可以帮助你处理频繁变更的需求的一种软件开发模式。
比如:

你的室友知道怎么开车去超市,再开回家。于是你可以告诉他去买一些东西,比如面包、奶酪、葡萄酒什么的。这相当于调用一goAndBuy 方法,把购物单作为参数。然而,有一天你在上班,你需要他去做一件他从来没有做过的事情:从邮局取一个包裹。现在你就需要传递给他一系列指示了:去邮局,使用单号,和工作人员说明情况,取走包裹。你可以把这些指示用电子邮件发给他,当他收到之后就可以按照指示行事了。你现在做的事情就更高级一些了,相当于一个方法: go ,它可以接受不同的新行为作为参数,然后去执行。

定义一个苹果类

package com.wenx.learn;

public class Apple {
    private Double weight;
    private String color;
    private AppleType appleType;

    public Apple(Double weight, String color, AppleType appleType) {
        this.weight = weight;
        this.color = color;
        this.appleType = appleType;
    }
    enum AppleType {
        HFS,JG,HX,JS;
    }
    public Double getWeight() {
        return weight;
    }
    public void setWeight(float weight) {
        this.weight = weight;
    }
    public String getColor() {
        return color;
    }
    public void setColor(String color) {
        this.color = color;
    }
    public AppleType getAppleType() {
        return appleType;
    }
    public void setAppleType(AppleType appleType) {
        this.appleType = appleType;
    }
    @Override
    public String toString() {
        return "Apple{" +
                "weight=" + weight +
                ", color='" + color + '\'' +
                ", appleType=" + appleType +
                '}';
    }
}

在一堆苹果中过滤需要的苹果

package com.wenx.learn;

import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;

import static org.junit.Assert.*;

public class AppleTest {

    private List apples = new ArrayList<>();

    @Before
    public void before() {
        apples.add(new Apple(10d,"红色", Apple.AppleType.HFS));
        apples.add(new Apple(13.2d,"绿色", Apple.AppleType.HX));
        apples.add(new Apple(28.5d,"黄色", Apple.AppleType.JG));
        apples.add(new Apple(5.9d,"红色", Apple.AppleType.JS));
        apples.add(new Apple(18.6d,"绿色", Apple.AppleType.HFS));
        apples.add(new Apple(14.7d,"黄色", Apple.AppleType.JS));
    }

    /**
     * 过滤苹果
     * @param apples
     * @param applePerdicate
     * @return
     */
    private List filterApples(List apples, Predicate applePerdicate){
        List filterApple = new ArrayList<>();
        for(Apple apple : apples) {
            if(applePerdicate.test(apple)){
                filterApple.add(apple);
            }
        }
        return filterApple;
    }

    @Test
    public void test1() {
        List appleList = filterApples(apples, apple -> apple.getColor().equals("红色"));
        appleList.forEach(System.out::println);
    }

}

结果
java8 基础知识_第1张图片
Predicate applePerdicate java8内置函数式接口
java8 基础知识_第2张图片
apple -> apple.getColor().equals(“红色”) lambda表达式

  1. 函数式接口
    只定义一个抽象方法的接口,可包含若干个默认方法(暂时忽略)
    predicate接口源码:
/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms
 */
package java.util.function;

import java.util.Objects;

/**
 * Represents a predicate (boolean-valued function) of one argument.
 *
 * 

This is a functional interface * whose functional method is {@link #test(Object)}. * * @param the type of the input to the predicate * * @since 1.8 */ @FunctionalInterface public interface Predicate { /** * Evaluates this predicate on the given argument. * * @param t the input argument * @return {@code true} if the input argument matches the predicate, * otherwise {@code false} */ boolean test(T t); /** * Returns a composed predicate that represents a short-circuiting logical * AND of this predicate and another. When evaluating the composed * predicate, if this predicate is {@code false}, then the {@code other} * predicate is not evaluated. * *

Any exceptions thrown during evaluation of either predicate are relayed * to the caller; if evaluation of this predicate throws an exception, the * {@code other} predicate will not be evaluated. * * @param other a predicate that will be logically-ANDed with this * predicate * @return a composed predicate that represents the short-circuiting logical * AND of this predicate and the {@code other} predicate * @throws NullPointerException if other is null */ default Predicate and(Predicate other) { Objects.requireNonNull(other); return (t) -> test(t) && other.test(t); } /** * Returns a predicate that represents the logical negation of this * predicate. * * @return a predicate that represents the logical negation of this * predicate */ default Predicate negate() { return (t) -> !test(t); } /** * Returns a composed predicate that represents a short-circuiting logical * OR of this predicate and another. When evaluating the composed * predicate, if this predicate is {@code true}, then the {@code other} * predicate is not evaluated. * *

Any exceptions thrown during evaluation of either predicate are relayed * to the caller; if evaluation of this predicate throws an exception, the * {@code other} predicate will not be evaluated. * * @param other a predicate that will be logically-ORed with this * predicate * @return a composed predicate that represents the short-circuiting logical * OR of this predicate and the {@code other} predicate * @throws NullPointerException if other is null */ default Predicate or(Predicate other) { Objects.requireNonNull(other); return (t) -> test(t) || other.test(t); } /** * Returns a predicate that tests if two arguments are equal according * to {@link Objects#equals(Object, Object)}. * * @param the type of arguments to the predicate * @param targetRef the object reference with which to compare for equality, * which may be {@code null} * @return a predicate that tests if two arguments are equal according * to {@link Objects#equals(Object, Object)} */ static Predicate isEqual(Object targetRef) { return (null == targetRef) ? Objects::isNull : object -> targetRef.equals(object); } }

Java 8中的常用函数式接口
java8 基础知识_第3张图片
java8 基础知识_第4张图片

  1. lambda表达式
    可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表。
    基本语法
    (parameters) -> expression
    或(请注意语句的花括号)
    (parameters) -> { statements; }
    java8 基础知识_第5张图片

  2. 方法引用
    方法引用可以被看作仅仅调用特定方法的Lambda的一种快捷写法。它的基本思想是,如果一个Lambda代表的只是“直接调用这个方法”,那最好还是用名称来调用它,而不是去描述如何调用它。
    事实上,方法引用就是让你根据已有的方法实现来创建Lambda表达式。但是,显式地指明方法的名称,你的代码的可读性会更好。
    苹果按重量排序

apples.sort((a,b) -> a.getWeight().compareTo(b.getWeight()));
等价于
apples.sort(Comparator.comparing(Apple::getWeight));

在这里插入图片描述
你可以把方法引用看作针对仅仅涉及单一方法的Lambda的语法糖,因为你表达同样的事情时要写的代码更少了。

你可能感兴趣的:(java8)