JDK1.8 新特性及高级用法

一、Lambda表达式

lambda表达式的语法:
(parameters) -> expression
或
(parameters) ->{ statements; }

(x)->{system.out.prinln} //直接打印x参数; 

示例:

public class LambdaTest {
    public static void main(String args[]){
        //开启一个新的线程
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("新线程:"+Thread.currentThread().getName());
            }
        }).start();

        System.out.println("主线程:"+Thread.currentThread().getName());
        System.out.println("==============================");
        /**
         * Lambda表达式是一个匿名函数,可以理解为一段可传递的代码
         * 优点:简化了匿名内部类的使用,语法更加简单。
         */
        new Thread(() -> {
            System.out.println("新线程lambda:"+Thread.currentThread().getName());
        }).start();

        System.out.println("==============================");
        List<Person> list = new ArrayList<Person>();
        list.add(new Person("薇恩",20));
        list.add(new Person("亚索",30));
        list.add(new Person("德玛西亚",18));
        Collections.sort(list,(p1,p2) -> p1.age-p2.age);
        for (Person p: list) {
            System.out.println("用户信息=>"+p.toString());
        }
    }

}

执行结果:

主线程:main
新线程:Thread-0
==============================
==============================
新线程lambda:Thread-1
用户信息=>Person(name=德玛西亚, age=18)
用户信息=>Person(name=薇恩, age=20)
用户信息=>Person(name=亚索, age=30)

二、函数式接口

函数式接口参数类型返回类型说明
Function< T, R > 函数型接口TRR apply(T t):对类型为T的对象应用操作,并返回类型为R类型的对象。
Consumer< T > 消费型接口Tvoidvoid accept(T t):对类型为T的对象应用操作。
Supplier< T > 供给型接口TT get():返回类型为T的对象。
Predicate< T > 断言型接口Tbooleanboolean test(T t):确定类型为T的对象是否满足条件,并返回boolean类型。

1. Function<T, R>: 函数型接口【R apply(T t)】

示例:

public class FunctionTest {

    public static void main(String[] args) {
        //奖金额翻10倍
        test(money -> Integer.parseInt(money)*10,"123");
    }

    public static void test(Function<String, Integer> function, String text) {
        //apply是一个有参有返回值的抽象方法
        Integer money = function.apply(text);
        System.out.println("money:"+money); // money:1230
    }
}

2. Consumer< T >: 消费型接口【void accept(T t)】

示例:

public class ConsumerTest {
    public static void main(String[] args) {
        toLowcase(msg -> System.out.println("转小写:"+msg.toLowerCase()), //转小写:hello world
                msg -> System.out.println("转大写:"+msg.toUpperCase()) //转大写:HELLO WORLD
                ,"Hello World");
        
    }
    public static void toLowcase(Consumer<String> c1,Consumer<String> c2, String text){
        //accept是一个有参无返回值的抽象方法
        //andThen 默认方法,先执行前面的,再执行后面的
        c1.andThen(c2).accept(text);
    }
}

3. Supplier< T >: 供给型接口【T get()】

示例:

public class SupplierTest {
    public static void main(String[] args) {
        fun1(() -> {
            int arr[] = {1,9,5,2,3};
            //排序
            Arrays.sort(arr);
            //返回最大值
            return arr[arr.length-1];
        });

    }

    public static void fun1(Supplier<Integer> supplier) {
        //get是一个无参有返回值的抽象方法
        Integer max = supplier.get();
        System.out.println("Max = "+max); // Max = 9
    }
}

4. Predicate< T >: 断言型接口【boolean test(T t)】

示例:

public class PredicateTest {

    public static void main(String[] args) {
        //判断长度是否大于3
        test(msg -> msg.length()>3,"HelloWorld");
    }

    public static void test(Predicate<String> predicate, String text) {
        //test是一个有参有返回值(boolean)的抽象方法
        boolean b = predicate.test(text);
        System.out.println("b:"+b); // b:true
    }
}

三、流API(Stream API)

1. 基础用法(forEach | filter | count | limit | skip | map | sorted | distinct | reduce | concat等)

示例:

public class StreamTest {
    public static void main(String args[]){
        //forEach、filter (元素循环/过滤)
        Stream.of("a1","a2","a3")
                .filter(s -> s.contains("1"))
                .forEach(s -> System.out.println(s)); // a1
        System.out.println("==========================");
        //count (元素计数)
        long count = Stream.of("a1","a2","a3")
                .count();
        System.out.println(count); // 3
        System.out.println("==========================");
        //limit (截取前面的几个元素)
        Stream.of("a1","a2","a3")
                .limit(2)
                .forEach(System.out::println); // a1 a2

        System.out.println("==========================");
        //skip (跳过前面的几个元素)
        Stream.of("a1","a2","a3")
                .skip(2)
                .forEach(System.out::println); // a3
        System.out.println("==========================");

        //map (将流中的元素映射到另一个流中)
        Stream.of("1","2","3")
                .map(Integer::parseInt)
                .forEach(System.out::println); // 1 2 3
        System.out.println("==========================");

        //sorted (元素排序)
        Stream.of("1","3","2","5","11")
                .sorted(Comparator.comparingInt(Integer::parseInt))
                .forEach(System.out::println); // 1 2 3 5 11
        System.out.println("==========================");

        //distinct (元素去重)
        Stream.of("1","3","2","5","1")
                .distinct()
                .forEach(System.out::println); // 1 3 2 5
        System.out.println("==========================");

        //reduce (缩减)
        Integer sum = Stream.of(1,3,2,5)
                //identity 为初始值
                //x:第一次会将默认值赋给x,后面将上一次的和复赋值给x
                //y:每次循环的值
                .reduce(0,(x,y) -> {
                    System.out.println("x="+x+",y="+y);
                    // x=0,y=1
                    // x=1,y=3
                    // x=4,y=2
                    // x=6,y=5
                    return x + y;
                });
        System.out.println("sum:"+sum); // sum:11

        //获取最大值
        Integer max = Stream.of(1, 3, 2, 5)
                //identity 为初始值
                //x:第一次会将默认值赋给x,后面将上一次的和复赋值给x
                //y:每次循环的值
                .reduce(0, (x, y) -> x > y ? x : y);
        System.out.println("max:"+max); // max:5
        System.out.println("==========================");


        //map与reduce混合使用
        Integer sum2 = Stream.of(
                new Person("张三", 18),
                new Person("李四", 22),
                new Person("王五", 17)
        )
                .map(Person::getAge) //收集年龄
                //.reduce(0,(x, y) -> x + y);
                .reduce(0,Integer::sum); //计算总数
                //.reduce(0,Integer::max); //取最大值


        System.out.println("sum2="+sum2); // sum2=57
        System.out.println("==========================");

        //concat (连接)
        Stream<String> s1 = Stream.of("aa","bb","cc");
        Stream<String> s2 = Stream.of("dd","ee","ff");
        Stream.concat(s1,s2).forEach(System.out::println);// aa bb cc dd ee ff

        System.out.println("====================================");
        //数据收集
        //收集到List
        List<String> list = Stream.of("aa", "bb", "cc", "aa").collect(Collectors.toList());
        System.out.println("收集到List:"+list.toString()); // 收集到List:[aa, bb, cc, aa]
        //收集到Set
        Set<String> set = Stream.of("aa", "bb", "cc", "aa").collect(Collectors.toSet());
        System.out.println("收集到Set:"+set.toString()); // 收集到Set:[aa, bb, cc]
        //收集到ArrayList
        ArrayList<String> arrayList = Stream.of("aa", "bb", "cc", "aa").collect(Collectors.toCollection(() -> new ArrayList<String>()));
        System.out.println("收集到ArrayList:"+arrayList.toString()); // 收集到ArrayList:[aa, bb, cc, aa]

        //收集到数组
        String[] strings = Stream.of("aa", "bb", "cc", "aa")
                    .toArray(String[]::new); //简写
        System.out.println("收集到数组:"+Arrays.toString(strings)); // 收集到数组:[aa, bb, cc, aa]

        System.out.println("============================");
        //聚合运算
        Optional<Person> collect = Stream.of(
                new Person("张三", 18),
                new Person("李四", 22),
                new Person("王五", 17)
        ).max(Comparator.comparingInt(Person::getAge));
        System.out.println("最大年龄:"+collect.get()); // 最大年龄:Person(name=李四, age=22)
        
    }
}

2. 高级用法

示例:

public class StreamExpertTest {
    /**
     * 用户对象
     */
    static class User{
        // 项目
        private String name;
        // 年龄
        private int age;
        // 爱好
        private String[] hobbies;

        public User(String name, int age, String[] hobbies) {
            this.name = name;
            this.age = age;
            this.hobbies = hobbies;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }

        public String[] getHobbies() {
            return hobbies;
        }

        public void setHobbies(String[] hobbies) {
            this.hobbies = hobbies;
        }

        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", hobbies=" + Arrays.toString(hobbies) +
                    '}';
        }

    }

    public static void main(String[] args) {
        // 初始化数据
        List<User> users = Arrays.asList(
                new User("张三", 22, new String[]{"足球", "篮球"}),
                new User("李四", 24, new String[]{"骑行", "爬山"}),
                new User("王五", 30, new String[]{"骑行", "撸代码"}),
                new User("赵六", 22, new String[]{"篮球", "乒乓球"}),
                new User("张七", 25, new String[]{"爬山", "撸代码"})
        );

        // 需求1:收集所有的用户姓名,并用逗号分割
        String names = users.stream()
                .map(User::getName)
                .collect(Collectors.joining(","));
        System.out.println("names=" + names); // names=张三,李四,王五,赵六,张七

        // 需求2:收集年龄为22的用户人数
        long count = users.stream()
                .filter(user -> user.getAge() == 22)
                .count();
        System.out.println("count=" + count); // count=2

        // 需求3:收集各年龄人数
        Map<Integer, Long> collect = users.stream()
                .collect(Collectors.groupingBy(User::getAge, Collectors.counting()));
        System.out.println("collect=" + collect); // collect={22=2, 24=1, 25=1, 30=1}

        // 需求4:收集所有爱好为字符串,逗号分隔,并去重
        String hobbies = users.stream()
                .flatMap(user -> Arrays.stream(user.getHobbies()))
                .distinct()
                .collect(Collectors.joining(","));
        System.out.println("hobbies=" + hobbies); // hobbies=足球,篮球,骑行,爬山,撸代码,乒乓球

        // 需求5:收集各自爱好为字符串,逗号分隔
        Map<String, String> userHobby = users.stream()
                .collect(Collectors.toMap(User::getName, user -> Arrays.toString(user.getHobbies())));
        System.out.println("userHobby=" + userHobby); // userHobby={李四=[骑行, 爬山], 张三=[足球, 篮球], 王五=[骑行, 撸代码], 张七=[爬山, 撸代码], 赵六=[篮球, 乒乓球]}



        // 需求6:收集hobbies为字符串数组List<String[]>
        List<String[]> hobbiesList = Arrays.stream(hobbies.split(","))
                .map(str -> new String[]{str})
                .collect(Collectors.toList());
        hobbiesList.stream().map(Arrays::toString).forEach(System.out::println);
        // [足球]
        // [篮球]
        // [骑行]
        // [爬山]
        // [撸代码]
        // [乒乓球]

        // 需求7:按年龄进行排序
        List<User> sortUsers = users.stream()
                .sorted(Comparator.comparingInt(User::getAge))
                .collect(Collectors.toList());
        sortUsers.forEach(System.out::println);
        // User{name='张三', age=22, hobbies=[足球, 篮球]}
        // User{name='赵六', age=22, hobbies=[篮球, 乒乓球]}
        // User{name='李四', age=24, hobbies=[骑行, 爬山]}
        // User{name='张七', age=25, hobbies=[爬山, 撸代码]}
        // User{name='王五', age=30, hobbies=[骑行, 撸代码]}

        // 需求8:收集年龄大于22的用户
        List<User> collectUsers = users.stream()
                .filter(user -> user.getAge() > 22)
                .collect(Collectors.toList());
        collectUsers.forEach(System.out::println);
        // User{name='李四', age=24, hobbies=[骑行, 爬山]}
        // User{name='王五', age=30, hobbies=[骑行, 撸代码]}
        // User{name='张七', age=25, hobbies=[爬山, 撸代码]}

        // 需求9:收集爱好包含骑行的用户
        List<User> collectUsers2 = users.stream()
                .filter(user -> Arrays.stream(user.getHobbies()).anyMatch(hobby -> hobby.contains("骑行")))
                .collect(Collectors.toList());
        collectUsers2.forEach(System.out::println);
        // User{name='李四', age=24, hobbies=[骑行, 爬山]}
        // User{name='王五', age=30, hobbies=[骑行, 撸代码]}

        // 需求10:收集姓名是张开头的用户
        // 创建一个 Predicate,用于判断名字是否以 "张" 开头
        Predicate<User> startsWithZ = user -> user.getName().startsWith("张");
        List<User> collectUsers3 = users.stream().filter(startsWithZ).collect(Collectors.toList());
        collectUsers3.forEach(System.out::println);
        // User{name='张三', age=22, hobbies=[足球, 篮球]}
        // User{name='张七', age=25, hobbies=[爬山, 撸代码]}

        // 需求11:收集用户姓名和爱好为Map<String, String[]>
        Map<String, String[]> userMap = users.stream()
                .collect(Collectors.toMap(
                        User::getName, // 名称
                        User::getHobbies, // 爱好
                        (oldValue, newValue) -> oldValue, // 如果名称重复,保留旧值
                        LinkedHashMap::new // 使用LinkedHashMap保持顺序
                ));

        userMap.forEach((key, value) -> System.out.println(key + "=" + Arrays.toString(value)));
        // 张三=[足球, 篮球]
        // 李四=[骑行, 爬山]
        // 王五=[骑行, 撸代码]
        // 赵六=[篮球, 乒乓球]
        // 张七=[爬山, 撸代码]

        // 需求12:收集用户姓名和用户对象为Map<String, User>
        Map<String, User> userMap2 = users.stream()
                .collect(Collectors.toMap(
                        User::getName, // 名称
                        Function.identity(), // 值映射函数,直接使用对象本身
                        (oldValue, newValue) -> oldValue, // 如果名称重复,保留旧值
                        LinkedHashMap::new // 使用LinkedHashMap保持顺序
                ));
        userMap2.forEach((key, value) -> System.out.println(key + "=" + value));
        // 张三=User{name='张三', age=22, hobbies=[足球, 篮球]}
        // 李四=User{name='李四', age=24, hobbies=[骑行, 爬山]}
        // 王五=User{name='王五', age=30, hobbies=[骑行, 撸代码]}
        // 赵六=User{name='赵六', age=22, hobbies=[篮球, 乒乓球]}
        // 张七=User{name='张七', age=25, hobbies=[爬山, 撸代码]}

        // 需求13:收集用户信息为固定格式,对象信息为数组字符串
        // 例如:"[{\"name\":\"张三\"}...]"
        Map<String, String> userMap3 = users.stream()
                .collect(Collectors.groupingBy(
                        User::getName, // 用户姓名-key
                        Collectors.mapping( // 映射为固定格式的对象信息
                                user -> "{\"name\":\"" + user.getName() + "\",\"age\":\"" + user.getAge() + "\",\"hobbies\":\"" + Arrays.toString(user.getHobbies()) + "\"}",
                                Collectors.joining(",", "[", "]")
                        )
                ));
        userMap3.forEach((key, value) -> System.out.println(key + "=" + value));
        // 李四=[{"name":"李四","age":"24","hobbies":"[骑行, 爬山]"}]
        // 张三=[{"name":"张三","age":"22","hobbies":"[足球, 篮球]"}]
        // 王五=[{"name":"王五","age":"30","hobbies":"[骑行, 撸代码]"}]
        // 张七=[{"name":"张七","age":"25","hobbies":"[爬山, 撸代码]"}]
        // 赵六=[{"name":"赵六","age":"22","hobbies":"[篮球, 乒乓球]"}]

    }
}

四、默认方法(default关键字修饰)

示例:

public interface StudyInterface {
    /**
     * 静态接口-学习
     */
    void study();

    /**
     * 默认接口-展示(default 关键字修饰)
     * 实现类可以根据具体需求是否需要实现该接口
     */
    default void show(){
        System.out.println("默认接口-show");
    }
}

五、时间API

示例:

public class LocalDateTest {
    public static void main(String args[]){

        //日期的操作
        LocalDate date = LocalDate.of(2024,10,25);
        System.out.println("date = "+date); // date = 2024-10-25
        //获取当前时间
        LocalDate now = LocalDate.now();
        System.out.println("now = "+now); // now = 2024-10-25

        System.out.println("年:"+now.getYear()); // 年:2024
        System.out.println("月:"+now.getMonth().getValue()); // 月:10
        System.out.println("日:"+now.getDayOfMonth()); // 日:25
        System.out.println("星期:"+now.getDayOfWeek().getValue()); // 星期:5

        System.out.println("===================================");

        //时间的操作
        LocalTime time = LocalTime.of(1,11,11);
        System.out.println("time = "+time); // time = 01:11:11
        LocalTime now1 = LocalTime.now();
        System.out.println("now1 = "+now1); // now1 = 14:55:59.931

        System.out.println(now1.getHour()); // 14
        System.out.println(now1.getMinute()); // 55
        System.out.println(now1.getSecond()); // 59
        System.out.println(now1.getNano()); // 931000000


        System.out.println("===========================");

        //获取当前日期时间
        LocalDateTime now3 = LocalDateTime.now();
        System.out.println("now3 = "+now3); // now3 = 2024-10-25T14:55:59.931
        //修改日期 修改后会返回一个新的日期对象,不会修改原来的值
        LocalDateTime date1 = now3.withYear(2023);
        System.out.println("原来日期:"+now3); // 原来日期:2024-10-25T14:55:59.931
        System.out.println("修改后日期:"+date1); // 修改后日期:2023-10-25T14:55:59.931

        //日期加减
        System.out.println("1年后:"+now3.plusYears(1)); // 1年后:2025-10-25T14:55:59.931
        System.out.println("6个月后:"+now3.plusMonths(6)); // 6个月后:2025-04-25T14:55:59.931
        System.out.println("10年前:"+now3.minusYears(10)); // 10年前:2014-10-25T14:55:59.931
        System.out.println("3天前:"+now3.minusDays(3)); // 3天前:2024-10-22T14:55:59.931

        //格式化日期
        DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String nowStr = format.format(now3);
        System.out.println("nowStr:"+nowStr); // nowStr:2024-10-25 14:55:59

        //将字符串解析为日期
        LocalDateTime parse = LocalDateTime.parse("2020-03-13 22:22:11",format);
        System.out.println("解析后日期:"+parse); // 解析后日期:2020-03-13T22:22:11


        //时间差 Duration
        Duration du = Duration.between(time,now1);
        System.out.println("相差天数:"+du.toDays()); // 相差天数:0
        System.out.println("相差小时数:"+du.toHours()); // 相差小时数:13
        System.out.println("相差分钟数:"+du.toMinutes()); // 相差分钟数:824

        //时间差 Period
        Period pe = Period.between(date,now);
        System.out.println("相差天数:"+pe.getDays()); // 相差天数:0
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

T-猿小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值