Java8特性

Java8中的Interface接口

interface接口的设计目的是面向接口编程,提高扩展性。

·Java8 中,接门中除了抽象方法外,还可以定义 default 默认方法和 static 静态方法。

  • default 修饰的默认方法,属于实例方法,可以被实现类调用或重写。0

         调用: 实现类必须 implements 接口,才能调用该接口的 default 默认方法。
         重写: 实现类 implements 不同接口时,接口中存在相同签名的方法(名称、参数、类型完全一致),则实现类必须重写该方法,明确方法定义;

·static 修饰的静态方法,属于类的静态方法。但它不能被子类继承,只能用 interface 接门名称调用。

lambda表达式

  • Lambda表达式本质是一个匿名函数,用于把函数作为参数,传入方法中,实现函数式编程风格。
  • 使用Lambda表达式可以使代码变得更加简洁紧凑

语法格式

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

函数式接口Functional Interface

        只有一个抽象方法的接口(可以定义多个非抽象方法)。可以使用@FunctionalInterface接口定义,强化语义规范。

         函数式接口,也被称为SAM接口(Single Abstract Method Interface)

作用

        基于函数式接口,可以使用Lambda表达式进行实现,实现函数式编程。

示例

示例1:排序

        函数式接口Comparaor

@FunctionalInterface
public interface Comparator<T>{
    int compare(T o1,T o2);
}

         使用Lambda实现函数式接口

//lambda表达式实现字符串数组排序
        List<String> list = null;
        list.sort((o1,o2)->{
           if (o1.length() == o2.length()){
               return o1.compareTo(o2);
           }
           return o1.length() - o2.length();
        });
        System.out.println(list);

示例2:迭代

        使用Lambda迭代遍历集合

List<String> langList = Arrays.asList("Basic","QBaisc","c","c++","PowerBuilder");
//方式一
for(String lang : langList){
    System.out.println(lang);
}

//方式二
langList.forEach((name)->{
    System.out.println(name);
});

内置函数式接口(Build-in Functional Interfaces)

        在Java8中专门有一个包放函数式接口java.util.function,该包下的所有接口都有@FunctionalInterface注解,提供函数式编程方式。

Predicate接口

        Predicate 接口是只有一个参数的返回布尔类型值的断言型接口。该接口包含多种默认方法来将 Predicate组合成其他复杂的逻辑 (比如: 与 and ,或 or ,非 negate):

        Predicate 断言型接口:

  List<String> langList = Arrays.asList("Basic","QBaisc","c","c++","PowerBuilder","C#");

        int len = 5;
        Predicate<String> predicateLen = (str)->{
            if(str.length() <= len){
                return true;
            }
            return false;
        };

        //判断前缀
        String prefix = "C";
        Predicate<String> predicatefix = (str)->{
            if(str.startsWith(prefix)){
                return  false;
            }
            return true;
        };

        //逻辑与
        Predicate<String> conditionAnd = predicateLen.and(predicatefix);

        //逻辑或
        Predicate<String> conditionOr = predicateLen.or(predicatefix);

        //逻辑非
        Predicate<String> conditionNot = predicateLen.negate();

        //遍历判断
        langList.forEach((name)->{
            if (conditionAnd.test(name)){
                System.out.println(name);
            }
        });


        langList.stream() //换行成Stream流
                .map((lang)->{ //map映射器
//                    return lang.toLowerCase();
                    return lang.length();
                })
                .forEach((lang)->{ //遍历
                    System.out.println(lang);
                });

Function

        Function接口接受一个参数并生成结果。默认方法可用于将多个函数链接在一起(compose,andThen)。

List<String> langList = Arrays.asList("Basic","QBaisc","c","c++","PowerBuilder","C#");

        //功能1:抓换成小写形式
        Function<String,String> fun1 = (lang)->{
            System.out.println("fun1");
            return lang.toLowerCase();
        };

        //功能2:添加括号
        Function<String,String> fun2 = (lang) ->{
            System.out.println("fun2");
            return String.format("<%s>",lang);
        };

        //组合
        Function<String,String> fun3 = fun1.andThen(fun2);
        Function<String,String> fun4 = fun1.compose(fun2);

        langList.stream()
                .map(fun3) //映射操作
                .forEach((lang)->{ //遍历
                    System.out.println(lang);
                });

Comparator

        比较器接口,用于比较指定元素值的大小。Java 8版本中,添加了多个新的default方法,用于比较器合并、反转等操作。

 List<String> langList = Arrays.asList("Basic","QBaisc","c","c++","PowerBuilder","C#");

        //两种比较规则
        //比较规则1:按照内容ASCII比较
        Comparator<String> comp1 = (x,y)->{
            return x.compareTo(y);
        };

        //比较规则2:按照长度
        Comparator<String> comp2 = (x,y)->{
            return x.length() - y.length();
        };

        //比较规则3:先比较内容,再比较长度
        Comparator<String> comp3 = comp1.thenComparing(comp2);

        //比较规则4:按照内容的降序
        Comparator<String> comp4 = comp1.reversed();

        //排序
        langList.sort(comp4);
        System.out.println(langList);

Stream流

  • java.util.Stream表示能应用在一组元素上一次执行的操作序列
  • Stream操作分为中间操作或者最终操作两种,最终操作返回一特定类型的计算结果,而中间操作返回Stream本身,可以联系完成多个操作。

创建Stream

        Stream的创建需要指定一个数据源。

//集合 ->Stream
List<String> list = Arrays.asList("稻香","七里香","东风破","青花瓷");

//数组 -> Stream
String[] array = {"稻香","七里香","东风破","青花瓷"};
Stream<String> arrayStream = list.stream();

常用方法

Filter过滤

        过滤通过一个predicate接口来过滤并只保留符合条件的元素,该操作数据中间操作。所以过滤后的结果,可以继续进行其它Stream操作(例如forEach,forEach需要一个函数来对过滤后的元素依次执行。forEach是一个最终操作)。

String[] array = {"稻香","七里香","东风破","青花瓷","稻香","七里香","爱如潮水"};

long count = Arrays.stream(array).filter((music)->{
                    return music.length() == 3;}) //先过滤
                    .count();
System.out.println(count);

Sorted排序

        排序是一个中间操作,返回的是排序好后的Stream。(不影响原数据)

//串行流
long count = values.stream().sorted().count();

//并行流
//        long count = values.parallelStream().sorted().count();

Map映射

        映射是一个中间操作,会将元素根据指定的Function接口来依次将元素转成另外的对象。

Match匹配

        Stream提供了多种匹配操作,允许检测指定的Predicate是否匹配整个Stream。所有的匹配操作都是最终操作,并返回一个boolean类型的值。

//是否存在一个名称长度为两个字的歌曲
boolean isContains1 = list.stream().anyMatch((music)->{return music.length() == 2;});
System.out.println(isContains1);

//所有歌曲全部都符合长度为2
boolean isContains2 = list.stream().allMatch((music)->{return music.length() == 2;});
System.out.println(isContains2);

//所有歌曲全部都不符合长度为1
boolean isContains3 = list.stream().noneMatch((music)->{return music.length() == 1;});
System.out.println(isContains3);

Count技术

        计数是一个最终操作,返回Stream中元素的个数,返回值类型是long

String[] array = {"稻香","七里香","东风破","青花瓷","稻香","七里香","爱如潮水"};

long count = Arrays.stream(array).filter((music)->{
                    return music.length() == 3;}) //先过滤
                    .count();
System.out.println(count);

Collect收集

        收集是一个最终操作,返回Stream中元素集合,返回值类型是集合(List、Set、Map)字符串。

将Stream中的元素,收集至新集合

  • Collectors.toList()
  • Collectors.toSet()
  • Collectors.toMap()
String[] array = {"稻香", "七里香", "东风破", "青花瓷", "稻香", "七里香", "爱如潮水"};

//distinct去重后,Stream中的元素收集成一个List
List<String> musicList = Arrays.stream(array).distinct().collect(Collectors.toList());
System.out.println(musicList);

//Stream中的元素收集成一个Set集合
Set<String> musicSet = Arrays.stream(array).collect(Collectors.toSet());
System.out.println(musicSet);

//distinct去重后,Stream中的元素收集成一个LinkedList
LinkedList<String> musicLinkedList =         
    Arrays.stream(array).distinct().collect(Collectors.toCollection(LinkedList::new));
System.out.println(musicLinkedList);

//Stream中的元素收集成一个LinkedHashSet集合
LinkedHashSet<String> musicLinkedSet = 
    Arrays.stream(array).collect(Collectors.toCollection(LinkedHashSet::new));
System.out.println(musicLinkedSet);

String[] array = {"稻香", "七里香", "东风破", "青花瓷", "稻香", "七里香", "爱如潮水"};

Stream<String> stream = Arrays.stream(array);

//将Stream流中的元素收集为一个Map集合
Map<String,Integer> resultMap1 = stream.distinct().collect(
                                        Collectors.toMap(
                                        (music)->{return music;},
                                         (music)->{return music.length();}));
System.out.println(resultMap1);

Map<String,Integer> resultMap2 = stream.distinct()
                                        .collect(
                                        Collectors.toMap(
                                        music->music,
                                        music->music.length()));
System.out.println(resultMap2);
  •  Collectors.mapping()   将Stream中的元素,映射后,收集至新集合
List<String> strlist = Arrays.asList("12","23","34","45","56","67");

//收集元素的同时,进行mapping映射操作
List<Integer> numList = strlist.stream().collect(
                        Collectors.mapping(
                        s->Integer.parseInt(s)*10,
                        Collectors.toList()));
System.out.println(strlist);
System.out.println(numList);
    
  •  Collectors.groupingBy()       将Stream中的元素,分组后,收集至Map集合
  • Collectors.partitioningBy()      将Stream中的元素,按照判断规则,统计分区后,收集至Map集合
List<String> nameList = Arrays.asList("曹操","曹丕","菠萝吹雪","张良","张忠","夏侯惇","夏侯","曹植");

Map<Character,List<String>> resultMap = nameList.stream().collect(
                                                Collectors.groupingBy(
                                                name->name.charAt(0)));

System.out.println(resultMap);

Map<Boolean,List<String>> resultPartingMap = nameList.stream()
                                                     .collect(Collectors.partitioningBy(
                                                     name->name.length()==2));
System.out.println(resultPartingMap);

Statistics统计

        统计是一个最终操作,返回Stream中元素的各类统计信息,返回值类型是XXXConsumer

List<Integer> number = Arrays.asList(1,2,4,5);

//List->Stream
Stream<Integer> stream = number.stream();

//Stream -> IntStream
IntStream intStream = stream.mapToInt(x->x);

//统计结果对象
IntSummaryStatistics statistics = intStream.summaryStatistics();
System.out.println("最大值:"+statistics.getMax());
System.out.println("最小值:"+statistics.getMin());
System.out.println("平均值:"+statistics.getAverage());
System.out.println("累加和:"+statistics.getSum());

Parallel Streams并行流

        Stream有串行和并行两种,串行Stream上的操作是在一个线程中依次完成,而并行Stream则是在多个线程上同时执行。

int max = 1000000;

List<String> values = new ArrayList<>(max);
for (int i = 0;i<max;i++){
    UUID uuid = UUID.randomUUID();
    values.add(uuid.toString());
}

long start = System.currentTimeMillis();

//串行流
long count = values.stream().sorted().count();

//并行流
//        long count = values.parallelStream().sorted().count();

long end = System.currentTimeMillis();
System.out.println(end-start);

函数式接口总结

  1. Predicate、Function、Consumer、Comparator
  2. 通过链式编程,使得它可以方便地对数据进行链式处理
  3. 方法参数都是函数式接口类型
  4. 一个Stream只能操作一次,操作完就关闭了,继续使用这个Stream会报错
  5. Stream不保存数据,不改变数据源

日期时间

Java 8 在java.time包下包含一个全新的日期和时间API

  • LocalDateTime //日期+时间   format:yyyy-MM-ddTHH:mm:ss.SSS
  • LocalDate //日期   format:yyyy-MM-dd
  • LocalTime //时间   format:HH:mm:ss

格式化


        //获取当前时间和日期
        LocalDate date = LocalDate.now();
        LocalTime time = LocalTime.now().withMinute(0);
        LocalDateTime dateTime = LocalDateTime.now();

        System.out.println(String.format("当前日期:%s",date));
        System.out.println(String.format("当前时间:%s",time));
        System.out.println(String.format("日期时间:%s",dateTime));
        System.out.println();

字符串日期格式

//类型转换
//字符串 ->LoaclDate
String strDate = "2023-08-19";
date = LocalDate.parse(strDate);
System.out.println(String.format("指定日期:%s",date));

//整数值->LocalDate
date = LocalDate.of(2023,8,19);
System.out.println(String.format("指定日期:%s",date));

//LoaclDate -> 字符串

日期计算

LocalDate date = LocalDate.now();

LocalDate after = date.plus(1, ChronoUnit.WEEKS);
System.out.println("一周后日期:"+after);

LocalDate before = date.plus(-1, ChronoUnit.WEEKS);
System.out.println("一周前日期:"+before);

//计算两个日期间隔多少天,多少年,多少月
LocalDate date1 = LocalDate.parse("2001-10-05");
LocalDate date2 = LocalDate.parse("2023-10-05");

Period result = Period.between(date1,date2);
System.out.printf("间隔%d年,%d月,%d日",result.getYears(),result.getMonths(),result.getDays());

//计算两个日期间隔:多少天
long days = date1.toEpochDay() - date2.toEpochDay();
System.out.println("间隔"+days+"天");

获取指定日期

//当前日期
LocalDate today = LocalDate.now();

//获取当前月第一天
LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
System.out.println("当前月第一天:"+firstDayOfMonth);

// 获取当前月最后一天
System.out.println("本月最后一天:"+today.with(TemporalAdjusters.lastDayOfMonth()));

//下个月第一天
System.out.println(today.with(TemporalAdjusters.lastDayOfMonth()).plusDays(1));

//本月的最后一个星期一
System.out.println(today.with(TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY)));

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值