functions

//1. Runnable   输入参数:无    返回类型void
new Thread(() -> System.out.println("In Java8!") ).start();
System.out.println();



//2.Predicate<T> 输入参数:t 返回类型boolean
List<String> languages = Arrays.asList("Java", "Scala", "C++", "Haskell", "Lisp");

// case1, 用流fliter,再 foreach遍历,传入Predicate 判断boolean
System.out.println("Languages which starts with J :");
filter(languages, (str)->str.startsWith("J"));
System.out.println();

Predicate<String> jSatrtConditions =(str)->str.startsWith("J");
Predicate<String> aEndsConditions =(str)->str.endsWith("a");

//case2, 两个&&关系
filter(languages, jSatrtConditions.and(aEndsConditions));
System.out.println();

//case3, 两个||关系
filter(languages, jSatrtConditions.or(aEndsConditions));
System.out.println();

//case4, 调用Predicate的静态isEqual方法
Predicate<String> predicateEqual = Predicate.isEqual("Java");
System.out.println(predicateEqual.test("JAVA"));

Predicate<String> and = predicateEqual.and(jSatrtConditions);
filter(languages, and);
System.out.println();



//3.Function<T,R> 输入参数:T 返回类型R
List<Integer> numList = Arrays.asList(100, 200, 300, 400, 500);
filter2(numList, n->n+1);
System.out.println();



//4.BiFunction<T, U, R> 输入参数:T,U 返回类型R
BiFunction<String, String,String> biFunction = (x,y)->x+y;
System.out.println(biFunction.apply("111", "222"));
System.out.println(biFunction.andThen(n->n+"*").apply("111", "222"));
System.out.println();



//5.BinaryOperator<T,T,T> 输入参数:T,T 返回类型T
//Represents an operation upon two operands of the same type, producing a result of the same type as the operands
Integer filter3Result = filter3(numList, n->n+1, (x,y)->x+y);
System.out.println(filter3Result);
System.out.println();


//第一步,和identity做相加生产新的数组
//第二步,新的数组每两个相乘
List<Integer> numList2 = Arrays.asList(1, 2, 3, 4, 5);
Integer filter4Result = filter4(numList2, 1, (x,y)->{
return x+y;
}, (x,y)->{
return x*y;
});
System.out.println(filter4Result);
System.out.println();


//6.Optional
//值不存在的情况下产生可替代物
ArrayList<String> arrayList = new ArrayList<>();

//(1) 创建Optional
//1) Optional.of() 它要求传入的 obj 不能是 null 值的, 否则还没开始进入角色就倒在了 NullPointerException 异常上了
Optional<String> stringOptional = Optional.of("stringOptional");
System.out.println(stringOptional.orElse(null));
System.out.println();

//2) Optional.ofNullable(obj): 它以一种智能的, 宽容的方式来构造一个 Optional 实例. 来者不拒, 传 null 进到就得到 Optional.empty(), 非 null 就调用 Optional.of(obj)
stringOptional = Optional.ofNullable(null);
System.out.println(stringOptional.orElse(null));
System.out.println();

//3) Optional.empty() 空的Optional
Optional<Object> emptyOptional = Optional.empty();
System.out.println(emptyOptional.orElse(null));
System.out.println();

//4) 自己创建
Optional<Double> inverseOptional = inverse(1.2);
System.out.println(inverseOptional.orElse(null));
System.out.println();


//(2) orElse() 值不存在的情况下的默认物
Optional<String> ofNullableOptional = Optional.ofNullable(null);
System.out.println(ofNullableOptional.orElse("default value"));

ofNullableOptional = Optional.empty();
System.out.println(ofNullableOptional.orElse("default value"));
System.out.println();


//(3) orElseGet() 值不存在的情况下, 提供Supplier
ofNullableOptional = Optional.ofNullable(null);
System.out.println(ofNullableOptional.orElseGet(()->new Date().toString()));

ofNullableOptional = Optional.empty();
System.out.println(ofNullableOptional.orElseGet(()->new Date().toString()));
System.out.println();


//(4) orElseThrow() 值不存在的情况下, 提供Supplier异常
try {
ofNullableOptional = Optional.ofNullable(null);
System.out.println(ofNullableOptional.orElseThrow(Exception::new));
} catch (Exception e) {
System.out.println("orElseThrow");
e.printStackTrace();
}
System.out.println();

try {
ofNullableOptional = Optional.empty();
System.out.println(ofNullableOptional.orElseThrow(Exception::new));
} catch (Exception e) {
System.out.println("orElseThrow");
e.printStackTrace();
}
System.out.println();


//(5) isPresent() 是否存在
boolean present = Optional.of("stringOptional").isPresent();
System.out.println(present);

present = Optional.empty().isPresent();
System.out.println(present);
System.out.println();


//(6) ifPresent() 如果存在,将元素传递给对应函数(比如将其加入集合或者做计算)
Optional.of("stringOptional").ifPresent(e->System.out.println(e));
Optional.of("stringOptional").ifPresent(System.out::println);

Optional.of("stringOptional").ifPresent(e->arrayList.add(e));

Optional.empty().ifPresent(e->System.out.println("xxx"));
System.out.println();


//(7) map() 将对应的值传递给mapper
Optional.of("map").map(e->arrayList.add(e));
System.out.println(arrayList);

Optional<Boolean> mapOptional = Optional.ofNullable("mapOptional").map(arrayList::add);
System.out.println(arrayList);

mapOptional = Optional.of("map").map(e->arrayList.add(e));
System.out.println(mapOptional.orElse(null));


//(8) get() 得到对应的值, 如果值不存在, 抛出exception
System.out.println(Optional.of("map").get());

//java.util.NoSuchElementException: No value present
// System.out.println(Optional.ofNullable(null).get());

Optional<Object> ofNullable = Optional.ofNullable(null);
if(ofNullable.isPresent()){
System.out.println(ofNullable.get());
}


//(9) flatMap() 组合两个返回Optional的方法 f(), g()
//方式一: f().float(T::g)
Optional<Double> flatMapOptional = inverse(1.2).flatMap(LambdaFunctionsTest::square);
System.out.println(flatMapOptional.orElse(null));
System.out.println();


//方式二: .float(T::f).float(T::g) 还可以在后面再.float(T::g)
flatMapOptional = Optional.of(1.2).flatMap(LambdaFunctionsTest::inverse).flatMap(LambdaFunctionsTest::square);
System.out.println(flatMapOptional.orElse(null));
System.out.println();

辅助方法

public static <T> void filter(List<T> names, Predicate<T> conditions){
names.stream().filter(conditions).forEach(name->System.out.println(name));
}

public static <T,R> void filter2(List<T> names, Function<T,R> function){
names.stream().map(function).forEach(name->System.out.println(name));
}

public static <T,R> R filter3(List<T> names, Function<T,R> mapFunction, BinaryOperator<R> binaryOperatorFunction){
return names.stream().map(mapFunction).reduce(binaryOperatorFunction).get();
}

public static <T,U,R> U filter4(List<T> names, U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> binaryOperatorFunction){
return names.stream().parallel().reduce(identity, accumulator, binaryOperatorFunction);
}

public static Optional<Double> inverse(Double t){
return null==t||t.equals(0) ? Optional.empty():Optional.of(1/t);
}

public static Optional<Double> square(Double t){
return null==t||t.equals(0) ? Optional.empty():Optional.of(Math.sqrt(t));
}