教程来源: Modern Java - A Guide to Java 8
1, 接口中的默认方法
接口中可以加入默认已经实现的方法
package com.demo;
public class DefaultMethod {
public static void main(String[] args) {
Formula Formula = new Formula() {
@Override
public int abs(int a) {
return a >= 0 ? a : -a;
}
};
System.out.println(Formula.abs(-10));
System.out.println(Formula.add(-100, 200));
System.out.println(Formula.minus(100, 200));
}
}
interface Formula{
int abs(int a);
default int add(int a, int b){
return a + b;
}
default int minus(int a, int b){
return a - b;
}
}
2, Lambda表达式
package com.demo;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class LambdaExpressionDemo {
public static void main(String[] args) {
List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
// // 1
// Collections.sort(names, (String a, String b) -> {
// return a.compareTo(b);
// });
// // 2
// Collections.sort(names, (String a, String b) -> a.compareTo(b));
// 3
Collections.sort(names, (a, b) -> a.compareTo(b));
System.out.println(names);
}
}
3, 函数式接口
package com.demo;
@FunctionalInterface
public interface FunctionalInterfaceDemo {
int add(int a, int b);
default int max(int a, int b){
return a>b?a:b;
}
}
4, 方法和构造器引用
a, 方法引用
package com.demo;
public class MethodReferDemo {
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
}
public static void main(String[] args) {
Converter<String, Integer> cvt = Integer::valueOf;
Integer result = cvt.convert("123");
System.out.println(result instanceof Integer);
}
}
b, 构造器引用
package com.demo;
public class MethodReferDemo {
public static void main(String[] args) {
PersonFactory<Person> personFactory = Person::new;
Person person = personFactory.create("Peter", "Parker");
System.out.println(person);
}
}
class Person {
String firstName;
String lastName;
Person() {}
Person(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return "Person [firstName=" + firstName + ", lastName=" + lastName + "]";
}
}
interface PersonFactory<P extends Person> {
P create(String firstName, String lastName);
}
We create a reference to the Person constructor via Person::new. The Java compiler automatically chooses the right constructor by matching the signature of PersonFactory.create.
5, lambda表达式作用域
5.1 访问外层局部变量
package com.demo;
public class LambdaScopeDemo {
@FunctionalInterface
interface Converter<F, T>{
F convert(T t);
}
public static void main(String[] args) {
int num = 1;
Converter<String, Integer> cvt = (t)-> String.valueOf(t+num);
System.out.println(cvt.convert(10)); // 11
}
}
被lambda表达式so使用的局部变量必须被final修饰, 不可改变的
5.2 访问对象字段和静态变量
package com.demo;
public class LambdaScopeDemo {
static int outerStaticNum;
int outerNum;
@FunctionalInterface
interface Converter<F, T>{
static int num = 100;
int plus = 0;
F convert(T t);
}
public static void main(String[] args) {
// outerStaticNum = 10;
// Converter<String, Integer> cvt = (t)-> String.valueOf(t+ outerStaticNum);
// outerStaticNum = 20;
// System.out.println(cvt.convert(10)); // 30
LambdaScopeDemo lambdaScopeDemo = new LambdaScopeDemo();
lambdaScopeDemo.outerNum = 10;
Converter<String, Integer> cvt = (t)-> String.valueOf(t+ lambdaScopeDemo.outerNum);
lambdaScopeDemo.outerNum = 20;
System.out.println(cvt.convert(10)); // 30
}
}
在使用到外部对象的字段或者静态变量时, 只有在计算的时候才会去取对象字段的值和静态变量
5.3 使用接口中的默认方法
接口中的默认方法不能lambda表达式所引用
6, 内置功能接口
6.1 Predicates
断言, 通过调用test方法来获取结果。还有negate (非), and(与), or(或)默认方法
package com.demo;
import java.util.function.Predicate;
public class PredicateDemo {
public static void main(String[] args) {
Predicate<String> predicate = (String a)->a.length()>0;
System.out.println(predicate.test("123"));
System.out.println(predicate.negate().test("123"));
}
}
6.2 Function<T, R>
快速方法, T:传入参数类型, R:结果参数类型, 只接受一个参数
package com.demo;
import java.util.function.Function;
public class FunctionsDemo {
public static void main(String[] args) {
Function<Integer, Integer> f = (a)->a/3;
Function<Integer, Integer> f2= (a)->a+3;
// compose 先执行传入的Function, 后执行自己
System.out.println(f.compose(f2).apply(30));
// andThen 先执行自己, 后执行传入的Function
System.out.println(f.andThen(f2).apply(30));
}
}
6.3 Supplier
不接受参数
package com.demo;
import java.util.function.Supplier;
public class SupplierDemo {
public static void main(String[] args) {
Supplier<String> s = String::new;
System.out.println(s.get().length());
}
}
6.4 Consumer
package com.demo;
import java.util.function.Consumer;
public class ConsumerDemo {
public static void main(String[] args) {
Consumer<String> c = (a)-> System.out.println(a);
c.accept("hello world");
}
}
7, Optional
能非常优雅的处理null
package com.demo;
import java.util.Optional;
public class OptionalDemo {
public static void main(String[] args) {
Optional<String> o = Optional.ofNullable(null);
// Optional<String> o = Optional.of("bam");
System.out.println(o.isPresent());
// System.out.println(o.get());
o.ifPresent((a)-> System.out.println(a.charAt(0)));
System.out.println(o.orElse("abd"));
}
}
8, Streams
package com.demo;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
public class StreamDemo {
public static void main(String[] args) {
List<String> stringCollection = new ArrayList<>();
stringCollection.add("ddd2");
stringCollection.add("aaa2");
stringCollection.add("bbb1");
stringCollection.add("aaa1");
stringCollection.add("bbb3");
stringCollection.add("ccc");
stringCollection.add("bbb2");
stringCollection.add("ddd1");
// filter过滤
stringCollection.stream().filter((a)->a.startsWith("a")).forEach(System.out::println);
System.out.println("---------------------");
// sorted
stringCollection.stream().filter((a)->a.startsWith("b")).sorted().forEach(System.out::println);
System.out.println("---------------------");
// map
stringCollection.stream().map(String::toUpperCase).sorted((a, b)->b.compareTo(a)).forEach(System.out::println);
System.out.println("---------------------");
// match
boolean anyMatch = stringCollection.stream().anyMatch(s -> s.startsWith("a"));
System.out.println("anyMatch:"+anyMatch);
boolean allMatch = stringCollection.stream().allMatch(s -> s.startsWith("a"));
System.out.println("allMatch:"+allMatch);
boolean noneMatch = stringCollection.stream().noneMatch(s -> s.startsWith("a"));
System.out.println("noneMatch:"+noneMatch);
System.out.println("---------------------");
long count = stringCollection.stream().filter(s -> s.startsWith("b")).count();
System.out.println(count);
System.out.println("---------------------");
Optional<String> optional = stringCollection.stream().sorted().reduce((s, s2) -> s + "," + s2);
optional.ifPresent(System.out::println);
}
}
8.1 filter
过滤, 中间操作
8.2 Sorted
排序, 中间操作
8.3 Map
转换(需要Functions 将所有元素执行方法), 中间操作
8.4 Match
最终结果操作 anyMatch: 有一个匹配就返回true allMatch: 所有匹配就返回true noneMatch: 没有一个匹配就返回true
8.5 count
返回结果的个数, 最终结果操作
8.6 reduce
最终结果操作
9,Parallel Streams
并行流
package com.demo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class ParalleStreamDemo {
public static void main(String[] args) {
int max = 1000000;
List<String> values = new ArrayList<>(max);
for (int i = 0; i < max; i++) {
UUID uuid = UUID.randomUUID();
values.add(uuid.toString());
}
sequentialSort(values);
Collections.shuffle(values);
paralleSort(values);
}
public static void sequentialSort(List<String> values){
long t0 = System.nanoTime();
long count = values.stream().sorted().count();
System.out.println(count);
long t1 = System.nanoTime();
long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
System.out.println(String.format("sequential sort took: %d ms", millis));
}
public static void paralleSort(List<String> values){
long t0 = System.nanoTime();
long count = values.parallelStream().sorted().count();
System.out.println(count);
long t1 = System.nanoTime();
long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
System.out.println(String.format("parallel sort took: %d ms", millis));
}
}
10, maps
package com.demo;
import java.util.HashMap;
import java.util.Map;
public class MapsDemo {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
// 不存在就put, 如果key存在不覆盖(和put的区别)
map.putIfAbsent(i, "val_" + i);
}
// map.forEach((integer, s) -> System.out.println(s));
String s1 = map.computeIfAbsent(3, s -> s + "_res");
System.out.println("s1:"+s1+", vale:"+map.get(3));
System.out.println("-----------------------");
String s2 = map.computeIfAbsent(23, s -> s + "_res");
System.out.println("s2:"+s2+", vale:"+map.get(23));
System.out.println("-----------------------");
map.computeIfPresent(3,(i, s) -> i+"_"+s);
System.out.println(map.get(3));
System.out.println("-----------------------");
// merge的biFunction函数将key对应map中的value作为第一个参数,将我们的第二的参数作为biFunction方法的第二个参数
map.merge(3,"hello", (s, s21) -> s+","+s21);
System.out.println(map.get(3));
}
}