學會lambda表達式,能讓你少敲1000行代碼!

01.什麼是 lambda 表達式

1. 函數式接口

在聊起 lambda 表達式以前,咱們不得不提起函數式接口:一個接口只包含惟一的方法,那麼它就是函數式接口。例如:java

public class LambdaTest {

    public static void main(String[] args) {
        Lambda lambda=new SonLambda();
        lambda.say();
    }
}

//1.一個接口只包含一個方法就是函數式接口
interface Lambda {
    void say();
}
//2.一個類實現接口,要重寫這個接口的全部方法
class SonLambda implements Lambda {
    @Override
    public void say() {
        System.out.println("i love lambda");
    }
}

有時候太懶的話咱們會直接寫一個匿名內部類web

public class LambdaTest {
    public static void main(String[] args) {
        //2.匿名內部類: 沒有子類,必須藉助接口或者父類
        Lambda lambda=new Lambda() {
            @Override
            public void say() {
                System.out.println("i like lambda");
            }
        };
        lambda.say();
    }
}
//1.一個接口只包含一個方法就是函數式接口
interface Lambda {
    void say();
}

可是咱們寫代碼確定是越懶(簡單)越好,這個時候 Lambda 表達式閃亮登場。數據庫

Lambda表達式是 Java8 發佈的最重要的新特性,它的出現就是爲了解決匿名內部類那一坨坨代碼的問題,讓代碼看起來更簡潔。express

lambda 表達式的語法格式以下:編程

(parameters) -> expression
或者
(parameters) ->{ statements;}

parameters 是參數,expression 是表達式。微信

對於上面例子中的匿名內部類,咱們用 Lambda 表達式該怎樣表示呢?app

由於上面例子中匿名內部類只有一個方法,因此咱們能夠省略掉它的接口名和方法名。eclipse

又由於沒有參數,因此咱們直接能夠用一箇中括號表示它的方法名,而後用->指向它的方法體。以下所示:() -> {}替代了匿名內部類。ide

public class LambdaTest {
    public static void main(String[] args) {
        Lambda lambda=()->{
            System.out.println("i like lombda");
        };
        lambda.say();
    }
}
//1.一個接口只包含一個方法就是函數式接口
interface Lambda {
    void say();
}

那麼你可能會問,帶有參數的接口用 lambda 表達式該怎樣表示呢?函數

以下所示:

public class LambdaTest {
    public static void main(String[] args) {
        Lambda lambda=(a,b)->{
            System.out.println("a="+a+" b="+b);
        };
        lambda.say(1,2);
    }
}
//1 一個接口只包含一個方法就是函數式接口
interface Lambda {
    void say(int a,int b);
}

02.Lambda 表達式經常使用方法

1. forEach 遍歷集合中的元素

List<String> fruits= Arrays.asList("apple", "orange", "banana");
fruits.forEach(fruit->{
           System.out.println("水果:"+fruit);
      });

2. stream流

Java8中的 stream 是對集合功能的加強,它專一於對集合進行各類很是便利、高效的聚合操做,或者大批量數據操做。

3. map()

獲取集合中的某一個元素,返回新的集合。記住使用map以前首先要得到集合的 stream 流。

public class LambdaTest {
    public static void main(String[] args) {
        //新增三我的的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"張無忌",25));
        list.add(new User(2,"趙敏",24));
        list.add(new User(3,"周芷若",23));
        //獲取這三我的的全部名字
        List<String> nameList = list.stream().map(User::getName).collect(Collectors.toList());
        //遍歷全部人的名字
        nameList.forEach(name->{
            System.out.println("名字:"+name);
        });
    }
}

4. collect(Collector c)

將操做以後的結果轉換爲集合,Collector 除了能夠轉爲list集合,還能轉爲set集合,也就是不重複的集合。

public class LambdaTest {
    public static void main(String[] args) {
        //新增三我的的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"張無忌",25));
        list.add(new User(2,"張無忌",24));
        list.add(new User(3,"周芷若",23));
        //獲取這三我的的全部名字
        Set<String> set = list.stream().map(User::getName).collect(Collectors.toSet());
        //遍歷全部人的名字
        set.forEach(name->{
            System.out.println("不重複的名字:"+name);
        });
    }
}

5. distinct() 去重

public class LambdaTest {
    public static void main(String[] args) {
        //新增三我的的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"張無忌01",25));
        list.add(new User(2,"張無忌01",24));
        list.add(new User(3,"趙敏",23));
        //獲取這三我的的全部名字
        List<String> nameList = list.stream().map(User::getName).distinct().collect(Collectors.toList());
        //遍歷全部人的名字
        nameList.forEach(name->{
            System.out.println("去重以後的名字:"+name);
        });
    }
}

6. reduce()

將元素中的值以某種方式鏈接起來,SQL中相似 sum()、avg() 或者 count() 的彙集函數,實際上就是 reduce 操做,由於它們接收多個值並返回一個值。

public class LambdaTest {
    public static void main(String[] args) {
        //新增三我的的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"張無忌",25));
        list.add(new User(2,"周芷若",24));
        list.add(new User(3,"趙敏",23));
        //1.獲取這三我的的年齡之和
        //2.map(w -> w.getAge()) 獲取每個人的年齡
        //3.reduce((x, y) -> x + y) 將他們的年齡相加
        //4.get() 獲取最後的結果
        Integer sumAge = list.stream().map(w -> w.getAge()).reduce((x, y) -> x + y).get();
        System.out.println("這三我的的年齡之和:"+sumAge);
    }
}

7. match用法

allMatch():檢查是否匹配全部元素

anyMatch(): 檢查是否匹配任意元素

noneMatch(): 檢查是否沒有匹配元素

public class LambdaTest {
    public static void main(String[] args) {
        //新增三我的的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"張無忌",25));
        list.add(new User(2,"周芷若",24));
        list.add(new User(3,"趙敏",23));
        boolean result01 = list.stream().allMatch(w->w.getAge()>23);
        boolean result02= list.stream().anyMatch(w->w.getAge()>23);
        boolean result03= list.stream().noneMatch(w->w.getAge()>23);
        System.out.println("全部人都大於23歲嗎?:"+result01);
        System.out.println("有大於23歲的嗎?:"+result02);
        System.out.println("他們沒有大於23歲的嗎?:"+result03);
    }
}

8. filter() 條件過濾

public static void main(String[] args) {
        //新增三我的的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"張無忌",25));
        list.add(new User(2,"周芷若",24));
        list.add(new User(3,"趙敏",23));
        //1.filter(w -> w.getAge() > 23) 年齡大於23
        //2.map(w -> w.getName()) 獲取人的名字
        //3.獲取這三我的中年齡大於23歲的人的名字的集合
        List<String> nameList = list.stream().filter(w -> w.getAge() > 23).map(w -> w.getName()).collect(Collectors.toList());
        nameList.forEach(name->{
            System.out.println("年齡大於23歲的人:"+name);
        });
    }

9. sorted() 排序

public static void main(String[] args) {
        //新增三我的的信息
        ArrayList<User> list = new ArrayList<>();
        list.add(new User(1,"張無忌",25));
        list.add(new User(2,"周芷若",24));
        list.add(new User(3,"趙敏",23));
        //1.sorted(Comparator.comparing(User::getAge)) 根據某個字段排序
        //2.reversed() 從大到小排序
        List<User> users1 = list.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
        System.out.println("-------------年齡從小到大排序");
        users1.forEach(user->{
            System.out.println(user.getName()+" "+user.getAge());
        });
        System.out.println("-------------年齡從大到小排序");
        List<User> users2 = list.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
        users2.forEach(user->{
            System.out.println(user.getName()+" "+user.getAge());
        });

    }

03.Lambda表達式常見案例

1. 案例一:獲取全部用戶的ID。

List<Integer> ids = list.stream().map(w -> w.getId()).collect(Collectors.toList());

2. 案例二:將全部用戶的 ID 做爲 key , name 做爲 value 放到一個map裏面。

Map<Integer, String> userMap = list.stream().collect(Collectors.toMap(User::getId,User::getName));

3. 案例三 :使用 stream 轉換爲集合,咱們不再用一個個去add了。

List<User> users = Stream.of(user1, user2, user3).collect(Collectors.toList());

4. 案例四:map 對象轉換,咱們通常從數據庫查數據爲 PO 對象,返回給web端時通常爲 VO 對象,那麼這其中就涉及對象轉換返回,map 就提供了便利的操做。

List<UserVo> userVos = userList.stream().map(user -> {
    UserVo userVo = new UserVo();
    BeanUtils.copyProperties(user, userVo);
    return userVo;
}).collect(Collectors.toList());

5. 案例五:按照某一個屬性進行分組,好比這裏咱們按照用戶性別進行分組。

Map<Integer, List<User>> genderGroup = userList.stream().collect(Collectors.groupingBy(User::getSex, Collectors.toList()));

6. 案例六:求最小、最大、平均值、求和。

int min = userList.stream().mapToInt(User::getAge).min().orElse(-1);
int max = userList.stream().mapToInt(User::getAge).max().orElse(-1);
int sum = userList.stream().mapToInt(User::getAge).sum();
double average = userList.stream().mapToInt(User::getAge).average().orElse(-1);

04.寫到最後

注意:lambda 表達式有個限制,那就是隻能引用final或final局部變量,這就是說不能在lambda內部修改定義在域外的變量,否則會報錯。

微信公衆號:eclipse編程。專一於編程技術分享,堅持終身學習。

相關文章
相關標籤/搜索