Q:最近接觸到Stream流式編程遇到了一些錯誤,故做一次總結複習用。
一、λ表達式
通常我們會用一個類實現接口,然後構造對象作爲參數傳入,也可以使用匿名類,用λ表達式可以簡化匿名類的編寫,用例如下。
class Worker implements Runnable {
@Override
public void run() {
// TODO: 2019/6/2
}
}
Thread t = new Thread(new Runnable() {
@Override
public void run() {
// TODO: 2019/6/2
}
});
Thread t1 = new Thread(new Worker());
Thread t2 = new Thread(()->{
// TODO: 2019/6/2
});
λ表達式語法:
(String str,...)->{ }
()->{}
()-> System.out.println();
表達式中引用的外部的變量,必須是 最終變量 final
List<Integer> list = new LinkedList<>();
list.forEach(System.out::println);//這裏是類的靜態方法,也可以是Object::instanceMethod,也可以是Class::instanceMethod
// System.out::println== x->sout(x) Math::pow == Math.pow(x,y)
也可以是 Class::new
List<String> list = Arrays.asList("zhangsan","lisi");
List<Person> res= list.stream().map(Person::new).collect(Collectors.toList());
System.out.println(res);
// [zhangsan, lisi]
list.forEach(e-> System.out.println(e)); //只有一行可以省略花括號
Comparator<String> c =(f,fs)->f.length-fs.length; //可推導出f fs 必然是字符串等價於(String f, String fs)則可以省略方法參數的類型
其中Comparator如下:
public interface Comparator<T> {
int compare(T o1, T o2);
}
函數式接口
public static <T> void sort(T[] a, Comparator<? super T> c)
Integer[] array = new Integer[]{3,2,1};
Arrays.sort(array,(o1, o2) -> o1-o2);
//sout 1,2,3
@FunctionalInterface
public interface BiFunction<T, U, R>{
R apply(T t, U u) //輸入T、U 返回 R類型
default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after); //輸入T、U 返回 R類型
return (T t, U u) -> after.apply(apply(t, u)); //然後將R傳入作爲參數傳入Function<? super R, ? extends V> after
}; //對於Function而言,傳入值爲V的子類,返回值是R的一種父類
}
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
常見函數式接口:
Stream 解析
stream of elements -----> filter ->sorted-> map -> collect
其中 Stream<T> filter(Predicate<? super T> predicate); 返回值爲Stream
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t) ; //校驗是否滿足條件
default Predicate<T> and(Predicate<? super T> other) { //且
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {//校驗是否不滿足條件
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
//sorted
Stream<T> sorted(); //元素自身需要實現 Comparable
Stream<T> sorted(Comparator<? super T> comparator);
// map 將集合中的元素轉換爲另外一種類型 ,同時返回的爲 Stream
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
----------------------------------------------------#### //reduce
Optional<T> reduce(BinaryOperator<T> accumulator);//流的第一個元素與第二個進行操作返回相同類型作爲第一個參數再次傳入
//如(x,y)->x+u 流爲:1,2,3,... 則(1,2)->3 (3,3)->6 .......
public interface BinaryOperator<T> extends BiFunction<T,T,T> { //BiFunction<T,T,T> T apply(T t, T u);
public static <T> BinaryOperator<T> minBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) <= 0 ? a : b;
}
public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
}
//用法
List<Integer> list = Arrays.asList(3, 2, 4, 1, 5, 6, 7); ///10
System.out.println(list.stream().reduce((a, b) -> a+ b).get()); //求和 T apply(T t, T u);
List<String> list = Arrays.asList("zhangsan","lisi","wangwu"); //拼接
System.out.println(list.stream().filter(e->e.length()>1)
.reduce((s, s2) -> s+","+s2).get());
BinaryOperator<Integer> bi = BinaryOperator.minBy(Comparator.naturalOrder());
System.out.println(bi.apply(2, 3)); //sout 2
--------------------------------------------------
T reduce(T identity, BinaryOperator<T> accumulator);//這裏同上,只是給出了一個初始值
<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner); //BiFunction<T, U, R>
//這裏U可以是不同類型,例如 是一個容器,可以存放流中處理的值
//第二個表達式中 輸入爲 T,U返回值爲U 即該方法第一個參數會作爲參數傳入,第三個參數只有在並行的時候纔有用,合併結果集
list.stream().reduce(new ArrayList<Integer>(), new BiFunction<ArrayList<Integer>, Integer, ArrayList<Integer>>() {
@Override
public ArrayList<Integer> apply(ArrayList<Integer> integers, Integer integer) {
integers.add(integer);
return integers;
}
}, new BinaryOperator<ArrayList<Integer>>() {
@Override
public ArrayList<Integer> apply(ArrayList<Integer> strings, ArrayList<Integer> strings2) {
return strings;
}
});
----------------------------------------------------------
collect
<R, A> R collect(Collector<? super T, A, R> collector);
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);