java 8 stream 入門javascript
在學習lambda
以前先來看一段代碼,傳入一個User的集合,返回符合條件的User集合java
public static List<User> filter(List<User> users, Predicate<User> predicate) {
List<User> result = new ArrayList<>();
for (User user: users){
if (predicate.test(user)) result.add(user);
}
return result;
}
複製代碼
代碼中使用了Predicate
接口, 接受一個泛型T,返回一個布爾值es6
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
複製代碼
java7中,咱們可使用匿名內部類
來做爲入參來調用filter
方法bash
public static List<User> filterZhang(List<User> users) {
return filter(users, new Predicate<User>() {
@Override
public boolean test(User user) {
return user.getName().startsWith("張");
}
});
}
複製代碼
java8中,咱們可使用lambda
來實現app
public static List<User> filterWang(List<User> users) {
return filter(users, user -> user.getName().startsWith("王"));
}
複製代碼
lambda實際上是一個箭頭函數
,也可稱爲匿名函數
,相似於ES6
中的箭頭函數,只不過javascript中使用=>
, 而java中使用->
ide
箭頭操做符將lambda表達式分紅了兩部分:函數
抽象方法
的參數列表)抽象方法
的實現)上面說到的抽象方法,指的就是Predicate接口中惟一的一個抽象方法 test,接收一個泛型T,返回boolean值post
boolean test(T t)
複製代碼
再看看咱們寫的lambda表達式, 是否是接受一個泛型爲User的user對象,若是user的姓王就返回true,反之返回false, 參數和返回值 一一對應學習
user -> user.getName().startsWith("王")
複製代碼
因此 lambda箭頭函數必須和Predicate
接口中那個惟一
的抽象方法保持一致(參數和返回值徹底相同),正由於如此,lambda中會對參數類型進行類型推斷
, 咱們只寫了一個user, java就知道這是一個User對象ui
語法有以下幾種格式:
() -> 具體實現
複製代碼
(x) -> 具體實現
//或
x -> 具體實現
複製代碼
(x,y) -> {具體實現}
複製代碼
注:lambda表達式的參數列表的參數類型能夠省略不寫,能夠進行類型推斷
。
函數式接口大部分定義在 java.util.function
包中, 且用@FunctionalInterface
註解
需求:須要對兩個數進行加減乘除等運算,怎麼實現?
public static void main(String[] args) {
add(2,1);
minus(2,1);
multiply(2,1);
divide(2,1);
}
static int add(int left, int right) {
return left + right;
}
static int minus(int left, int right) {
return left - right;
}
static int multiply(int left, int right) {
return left * right;
}
static int divide(int left, int right) {
return left / right;
}
複製代碼
public static void main(String[] args) {
calc(2, 1, (left, right) -> left + right);
calc(2, 1, (left, right) -> left - right);
calc(2, 1, (left, right) -> left * right);
calc(2, 1, (left, right) -> left / right);
}
static int calc(int left, int right, Calculate calculate) {
return calculate.applyAsInt(left, right);
}
@FunctionalInterface
interface Calculate {
int applyAsInt(int left, int right);
}
d
複製代碼
因此用lambda的話,只須要定義一個函數式接口,無論進行什麼操做,均可以用lambda解決,不用再一種運算對應一個方法。可是,還須要本身定義函數式接口,好像也沒簡單不少。Java考慮到這點了,因此內置了函數式接口, 大部分放在java.util.function
包中, 接口用@FunctionalInterface
註解。
如Predicate接口
在將lambda時舉的例子,能夠換成方法引用
的寫法
public static List<User> filterLi(List<User> users) {
return filter(users, Demo1::test);
}
// test 至關於 Predicat接口中抽象方法test的實現
private static boolean test(User user) {
return user.getName().startsWith("李");
}
複製代碼