Lambda使用——JDK8新特性

导读:本篇文章讲解 Lambda使用——JDK8新特性,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

Lambda 简介

Lambda表达式是JDK8的新特性,可以取代大部分的匿名内部类,写出更简洁更优雅的Java代码,同时JDK也提供了大量的内置函数式接口供我们使用,使得Lambda表达式运用更加方便和高效。

Lambda 表达式

语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。
能够接收Lambda表达式的参数类型,是一个只包含一个方法的接口。只包含一个方法的接口称之为“函数接口”。

举个例子:
创建一个线程

// 创建一个匿名线程
Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("hello world");
    }
});
t.start();

Lambda方式创建一个匿名线程

// Lambda方式创建一个匿名线程
Thread t = new Thread(() -> System.out.println("hello world"));
t.start();

Lambda 常用测试

User对象

package flinktest.method;

import lombok.Data;

@Data
public class User {
    private String username;
    private String password;
    private Integer age;
}

测试代码如下:

package flinktest.method;

import org.junit.Before;
import org.junit.Test;

import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

public class FunctionMethodTest {

    List<User> userList = new ArrayList<>();

    /**
     * 初始化参数
     */
    @Before
    public void init() {
        String[] usernames = {"韩菱纱", "柳梦璃", "云天河", "慕容紫英", "玄霄"};
        for (int i = 0, len = usernames.length; i < len; i++) {
            User user = new User();
            user.setUsername(usernames[i]);
            user.setPassword("123456");
            user.setAge(ThreadLocalRandom.current().nextInt(16, 18));
            userList.add(user);
        }
        System.out.printf("原始数据: ");
        System.out.println(userList);
    }


    /**
     * 获取用户名
     */
    @Test
    public void testGetUsername() {
        userList.stream().forEach(e -> System.out.println(e.getUsername()));
    }

    /**
     * 找到第一个对象
     */
    @Test
    public void testFindFirst() {
        Optional<User> user = userList.stream().findFirst();
        System.out.println(user.get());
    }

    /**
     * 计数
     */
    @Test
    public void testCount() {
        long count = userList.stream().count();
        System.out.println(count);
    }

    /**
     * 过滤出来 age>=16 的对象
     */
    @Test
    public void testFilter() {
        List<User> collect = userList.stream().filter(user -> user.getAge() >= 16).collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * 按照id正序排列
     */
    @Test
    public void testSorted() {
        List<User> collect = userList.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * 按照id倒叙排列
     */
    @Test
    public void testSortedReversed() {
        List<User> collect = userList.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
        System.out.println(collect);
    }

    /**
     * 年龄求和
     */
    @Test
    public void testSum() {
        int sum = userList.stream().mapToInt(User::getAge).sum();
        System.out.println(sum);
    }

    /**
     * 年龄求平均
     */
    @Test
    public void testAverage() {
        Double average = userList.stream().mapToDouble(User::getAge).average().getAsDouble();
        System.out.println(average);
    }

    /**
     * 年龄最大最小
     */
    @Test
    public void testMaxMin() {
        int max = userList.stream().mapToInt(User::getAge).max().getAsInt();
        System.out.println(max);

        int min = userList.stream().mapToInt(User::getAge).min().getAsInt();
        System.out.println(min);
    }

    /**
     * 年龄分组
     */
    @Test
    public void testGroupBy() {
        Map<Integer, List<User>> collect = userList.stream().collect(Collectors.groupingBy(User::getAge));
        System.out.println(collect);
    }

    /**
     * 聚合函数测试
     */
    @Test
    public void testAggregation() {
        //得到一个DoubleSummaryStatistics对象,里面包含dcompQty字段的各种统计值;如果是int类型或者是long类型,需要修改对应的对象
        DoubleSummaryStatistics qtySummary = userList.stream().collect(Collectors.summarizingDouble(e -> Double.valueOf(e.getAge())));
        Map<String, String> qtyMap = new HashMap<>();
        qtyMap.put("MAXNUM", String.valueOf(qtySummary.getMax())); //根据age分组后dcompQty的最大值
        qtyMap.put("MINNUM", String.valueOf(qtySummary.getMin())); //根据age分组后dcompQty的最小值
        qtyMap.put("SUMNUM", String.valueOf(qtySummary.getSum())); //根据age分组后dcompQty的和值
        qtyMap.put("AVGNUM", String.valueOf(qtySummary.getAverage())); //根据age分组后dcompQty的平均值
        qtyMap.put("COUNTNUM", String.valueOf(qtySummary.getCount())); //根据age分组后dcompQty的个
        System.out.println(qtyMap);
    }
}

Optional 常用方法测试

package flinktest;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;

import static org.junit.Assert.*;

@Slf4j
public class OptionalTest {

    /**
     * Optional.of 方法参数一定不能是null
     */
    @Test
    public void testof() {
        Optional<String> optional = Optional.of("hello");
        assertTrue(optional.isPresent());
    }


    /**
     * Optional.ofNullable 方法参数可以是null
     */
    @Test
    public void testofNullable() {
        Optional<String> optional1 = Optional.ofNullable(null);
        assertFalse(optional1.isPresent());

        Optional<String> optional2 = Optional.ofNullable("hello");
        assertTrue(optional2.isPresent());
    }

    /**
     * optional1.isPresent 判断Optional是否有值返回值是boolean类型
     */
    @Test
    public void testisPresent() {
        Optional<String> optional1 = Optional.ofNullable(null);
        assertFalse(optional1.isPresent());

        Optional<String> optional2 = Optional.ofNullable("hello");
        assertTrue(optional2.isPresent());
    }

    /**
     * optional1.ifPresent 如果Optional有值,执行后面的方法
     */
    @Test
    public void testifPresent() {
        Optional<String> optional1 = Optional.ofNullable(null);
        optional1.ifPresent(name -> System.out.println(name));

        Optional<String> optional2 = Optional.ofNullable("hello");
        optional2.ifPresent(name -> System.out.println(name));
    }

    /**
     * orElse 返回Optional包裹的值,如果为null,则返回函数内的默认值
     */
    @Test
    public void testorElse() {
        String nullName = null;
        String name = Optional.ofNullable(nullName).orElse("default");
        assertEquals("default", name);
    }

    /**
     * orElseGet 返回Optional包裹的值,如果为null,则返回函数内的默认值。
     * 区别于orElse的是orElseGet后面跟的是表达式方法,可以实现一些业务逻辑
     */
    @Test
    public void testorElseGet() {
        String nullName = null;
        String name = Optional.ofNullable(nullName).orElseGet(() -> "default");
        assertEquals("default", name);
    }

    /**
     * get 获取Optional里面的值。
     * 一定不能是null,null会抛出异常:java.util.NoSuchElementException: No value present
     * 如果不能确定是否有null,不建议直接使用get方法,可以使用orElseGet
     */
    @Test
    public void testget() {
        String nullName = null;
        String name = Optional.ofNullable(nullName).get();
        System.out.println(name);
    }
    
    /**
     * map和flatMap均要求optional对象非空才执行mapper方法,二者均返回Optional对象。但是map会自动将计算结果封装为Optional对象,而flatMap需要自己进行封装
     */
    @Test
    public void testmap() {
        List<String> list = Arrays.asList("hello world", "i love java");
        list.stream().map(String::toUpperCase).forEach(s -> System.out.println(s + ","));
        // 下面这一行会报语法错误
//        list.stream().map(s -> Stream.of(s.split(" "))).map(String::toUpperCase).forEach(s -> System.out.println(s + ","));
    }

    /**
     * map和flatMap均要求optional对象非空才执行mapper方法,二者均返回Optional对象。但是map会自动将计算结果封装为Optional对象,而flatMap需要自己进行封装
     *
     * 官方对flatmap的解释:
     * Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.
     *
     */
    @Test
    public void testflatMap() {
        List<String> list = Arrays.asList("hello world", "i love java");
        list.stream().flatMap(s -> Stream.of(s.split(" "))).map(String::toUpperCase).forEach(s -> System.out.println(s + ","));
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/72616.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!