Java 8所做的改变,在许多方面比Java历史上任何一次改变都深远。
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);
}
}
结果
Predicate applePerdicate java8内置函数式接口
apple -> apple.getColor().equals(“红色”) lambda表达式
/*
* 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 super T> 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 super T> 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);
}
}
lambda表达式
可以把Lambda表达式理解为简洁地表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表。
基本语法
(parameters) -> expression
或(请注意语句的花括号)
(parameters) -> { statements; }
方法引用
方法引用可以被看作仅仅调用特定方法的Lambda的一种快捷写法。它的基本思想是,如果一个Lambda代表的只是“直接调用这个方法”,那最好还是用名称来调用它,而不是去描述如何调用它。
事实上,方法引用就是让你根据已有的方法实现来创建Lambda表达式。但是,显式地指明方法的名称,你的代码的可读性会更好。
苹果按重量排序
apples.sort((a,b) -> a.getWeight().compareTo(b.getWeight()));
等价于
apples.sort(Comparator.comparing(Apple::getWeight));