Java 8 特性

Java 8 特性

👏被函数式接口@FunctionalInterface(即SAM接口)修饰,表示接口内的抽象方法有且只有一个

此时可使用lambda表达式对带有此注解的接口中抽象方法进行实现

Lambda表达式:用于将函数作为参数,传入方法中,实现函数式编程风格

java 复制代码
(parameters)->expression 或 (parameters)->{statements;} 

例子:

1️⃣排序

java 复制代码
//传统方法
list.sort(new Comparator<String>() {
    @Override
    public int compare(String o1, String o2) {
        return o1.length()-o2.length();
    }
});
//lambda表达式---省略多余的,看最内部的主要起作用的方法是啥(关注参数和返回值)
list.sort((o1, o2) -> {return o1.length() - o2.length();});

2️⃣将list中名称变成大写

java 复制代码
//对foreach方法中consumer接口的accept方法(无返回值)
list.forEach((s) -> {System.out.println(s.toUpperCase());});

3️⃣按照条件删除list中部分元素

java 复制代码
//删除list中以b开头的元素
list.removeIf((lang)->{
            if(lang.startsWith("b")){
                return true;
            }
            return false;
});

内置函数式接口

Predicate接口

只有一个参数的返回布尔类型值的断言型接口------应用于判断

java 复制代码
ArrayList<String> langList = new ArrayList<(Arrays.asList("abc","bv","aaac","a"));

4️⃣查找list中元素字符小于3个字符的元素

java 复制代码
Predicate<String> predicate1 =(lang)->{
            if (lang.length()<=3){
                return true;
            }
            return false;
        };

5️⃣查找list中元素以a或者b开头的元素

java 复制代码
Predicate<String> predicate2 = (lang)->{
            if(lang.toLowerCase().startsWith("a")||lang.toLowerCase().startsWith("b")){
                return true;
            }
            return false;
        };

6️⃣条件组合:形成"与","或","非"的逻辑关系

java 复制代码
Predicate<String> predicate3 = predicate1.and(predicate2);
Predicate<String> predicate4 = predicate1.or(predicate2);
Predicate<String> predicate5 = predicate1.negate();
//输出
langList.forEach((lang)->{
            if(predicate3.test(lang)){
                System.out.println(lang);
            }
        });

Function接口

接收一个参数并产生结果----对数据作处理

7️⃣list转换成大写字母形式

java 复制代码
Function<String,String> function1 = (lang)->{
            lang = lang.toUpperCase();
            return lang;
        };

8️⃣list每项加上【】

java 复制代码
Function<String,String> function2 = (lang)->{
            lang = String.format("【%s】",lang);
            return lang;
        };

9️⃣组合

java 复制代码
Function<String,String> function3 = function1.andThen(function2);
langList.forEach((lang)->{
    String ret = function3.apply(lang);
    System.out.println(ret);
});

Comparator接口

比较器接口,比较指定元素值的大小

1️⃣0️⃣比较

java 复制代码
Comparator<String> comparator1 = (lang1,lang2)->{
            int ret = lang1.compareTo(lang2);
            if(ret == 0){
                /**
                 * 比较两个字符串,返回它们长度的差值
                 * 返回值
                 *      负数:lang1的长度小于lang2的长度
                 *      正数:lang1的长度大于lang2的长度
                 */
                return lang1.length()-lang2.length();
            }
            return  ret;
        };

1️⃣2️⃣反转

java 复制代码
Comparator<String> comparator2 = comparator1.reversed();

1️⃣3️⃣排序

java 复制代码
langList.sort(comparator1);
//输出
langList.forEach((lang)->{
    System.out.println(lang);
});

Stream流

应用在一组元素上一次执行的操作系列

1️⃣4️⃣Stream创建

java 复制代码
ArrayList<String> langList = new ArrayList<>(Arrays.asList("abc","bv","aaac","a","abc","aaac"));
//通过集合对象创建
Stream<String> stream = langList.stream();
//通过Stream.of()方法创建
Stream<String> stream1 = Stream.of("abc", "bv", "aaac", "a", "abc", "aaac");

1️⃣5️⃣过滤集合中的元素(字符数大于5个的元素),并去重

java 复制代码
stream
    //过滤集合中的元素(字符数大于5个的元素)
    .filter((lang)->{
        if(lang.length() >=3){
            return true;
        }
        return false;
    })
    //去重
    .distinct()
    //输出
    .forEach((lang)->{
        System.out.println(lang);
    });

Filter过滤

过滤通过一个predicate接口来过滤并只保留符合条件的元素,该操作属于中间操作,过滤后的结果仍旧可以继续执行其他Stream操作

1️⃣6️⃣过滤Stream中纯小写字母并排序

java 复制代码
stream
    //过滤
    .filter((lang)->{
        for(int i = 0; i<lang.length();i++){
            char c = lang.charAt(i);
            if(c >='A'&& c<='Z'){
                return true;
            }
        }
        return false;
    })
    //排序
    .sorted((o1,o2)->{
        if(o1.length() == o2.length()){
            return o1.compareTo(o2);
        }
        return o1.length()-o2.length();
    })
    //遍历
    .forEach((lang)->{
        System.out.println(lang);
    });

Sorted排序

中间操作,返回的是排序好后的Stream,不影响原来的数据

Map映射

中间操作,将元素根据指定的function接口来依次将元素转成另外的对象

1️⃣7️⃣转换String字符串为大写,降序后,输出

java 复制代码
Stream<Integer> stream1 = Stream.of(10, 20, 30, 40, 50, 60);
//映射:对每个元素进行一次处理
stream1.map((n)->{
    return  n+1;
}).forEach((n)->{
    System.out.println(n);
});
List<String> strings = Arrays.asList("abc","bv","aaac","a");
//转换字符串为大写,降序后,输出
strings.stream().map((item)->{
    return item.toUpperCase();
}).sorted((s1,s2)->{
    return s2.compareTo(s1);
}).forEach((item)->{
    System.out.println(item);
});

Match匹配

最终操作,返回一个boolean类型的值

1️⃣8️⃣元素匹配

java 复制代码
//allMatch:所有元素是否匹配
boolean bool1= strings.stream().allMatch((item)->{
    return item.length()==3;
});
System.out.println(bool1);

//anyMatch:任意元素匹配
boolean bool2 =strings.stream().anyMatch((item)->{
    return item.length()==3;
}) ;
System.out.println(bool2);

Count计数

最终操作,返回Stream中元素个数,返回值是long

1️⃣9️⃣找到stram中所有以a开头的名称,并统计数量

java 复制代码
long count = strings.stream().filter((item)->{
            return item.startsWith("a");
        }).count();
System.out.println(count);

Collect收集

最终操作,返回Stream中元素集合,返回值是集合(List、Set、Map)或者字符串

2️⃣0️⃣将Stream中的元素,收至新集合

  • Collectors.toMap()
  • Collectors.toList()
  • Collectors.toSet()
java 复制代码
//转换为Map键值对集合:
Map<?,?> map = strings.stream().collect(Collectors.toMap(
    (s) -> {return s;},
    (sVal) ->{return sVal.length();}
));
System.out.println(map);

2️⃣1️⃣将Stream中的元素,映射后,收集至新集合

java 复制代码
List<String> numberStrings = Arrays.asList("4344","6641","3432","4543","2222");
//将stream流中的每个元素进行mapping映射操作后,然后收集至一个list集合
List<Integer> numberInt = numberStrings.stream().collect(Collectors.mapping(s->Integer.parseInt(s)*10,Collectors.toList()));
        numberInt.forEach(System.out::println);
System.out.println();

2️⃣2️⃣分组操作和分区操作

java 复制代码
 /**
         * 分组操作
         */
Stream<String> stream = Stream.of("Basic", "Qbsif", "Html", "CCD", "Hello!");
//按照元素的字符长度,进行分组
Map<Integer, List<String>> resultMap = stream.collect(Collectors.groupingBy(s -> s.length()));
resultMap.forEach((k,v)->{
    System.out.println(k+":"+v);
});
System.out.println("-----------------");
Stream<String> stream2 = Stream.of("Basic", "Qbsif", "Html", "CCD", "Hello!");
//按照元素首字母进行分组
Map<Character, List<String>> resultMap2 =stream2.collect(Collectors.groupingBy(s->s.charAt(0)));
resultMap2.forEach((k,v)->{
    System.out.println(k+":"+v);
});
System.out.println("-----------------");

/**
         * 分区操作
         */
Stream<String> stream3 = Stream.of("Basic", "Qbsif", "Html", "CCD", "Hello!");
Map<Boolean, List<String>> map = stream3.collect(Collectors.partitioningBy(s -> s.length() > 4));
map.forEach((k,v)->{
    System.out.println(k+":"+v);
});

👏Map集合补充:

2️⃣3️⃣Map集合的遍历

java 复制代码
map.forEach((k,v)->{System.out.println(k+":"+v);});

2️⃣4️⃣Map键值对合并

java 复制代码
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("HuaWei MateXT",9999);
map.put("联想小新",6666);
map.put("三星手机",7890);

//Map键值对合并
//key存在,执行合并操作
map.merge("三星手机",10,(olaVal,newVal)->{
    return olaVal + newVal;
});
//键不存在,放入map中
map.merge("小米手机",5000,(olaVal,newVal)->{
    return olaVal + newVal;
});

Statistics统计

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

stream流必须是IntStream

2️⃣5️⃣统计操作

java 复制代码
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
//Stream===>IntStream
IntStream intStream = list.stream().mapToInt(s -> s * 10);
//获取统计结果
IntSummaryStatistics statisticsResult = intStream.summaryStatistics();

System.out.println("最大值"+statisticsResult.getMax());
System.out.println("最小值"+statisticsResult.getMin());
System.out.println("平均值"+statisticsResult.getAverage());
System.out.println("累加和"+statisticsResult.getSum());

一个Stream只能操作一次,操作完就关闭了,继续使用这个Stream会报错

Stream不保存数据,不该表数据源

Parallel Streams并行流

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

日期时间

2️⃣6️⃣格式化

java 复制代码
//默认格式:yyyy-MM-dd
LocalTime date = LocalTime.now();
System.out.println(String.format("Date format:%s",date));

//默认格式:HH:mm:ss
LocalTime time = LocalTime.now().withNano(0);
System.out.println(String.format("Time format:%s",time));

//自定义格式:yyyy-MM-dd HH:mm:ss
LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:ss:dd");
String dateTimeStr = dateTime.format(dateTimeFormatter);
System.out.println(String.format("DateTime format:%s",dateTimeStr));

2️⃣7️⃣字符串转日期格式

java 复制代码
//字符串格式的日期
String strDatetime = "2024年12月17日";
//将字符串格式的日期转换为LocalDate类型的日期
LocalDate date1 = LocalDate.parse(strDatetime, DateTimeFormatter.ofPattern("yyyy年MM月dd日"));
System.out.println(date1);

2️⃣8️⃣日期的计算

java 复制代码
//计算一周后的日期
LocalDate localDate = LocalDate.now();
//方法1
LocalDate after1 = localDate.plus(1, ChronoUnit.WEEKS);
System.out.println("一周后日期"+after1);
//方法2
LocalDate after2 = localDate.plusWeeks(1);
System.out.println("一周后日期"+after2);
//计算两个日期间隔多少天,计算间隔多少年,多少月
LocalDate date1 = LocalDate.parse("2021-02-26");
LocalDate date2 = LocalDate.parse("2022-02-26");
Period period = Period.between(date1,date2);
System.out.println("date1到date2相隔"+period.getYears()+"年"+period.getMonths()+"月"+period.getDays()+"日");

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

2️⃣9️⃣获取指定日期

java 复制代码
 LocalDate today = LocalDate.now();
//获取当前月的第一天
LocalDate firstDayOfMonth = today.with(TemporalAdjusters.firstDayOfMonth());
System.out.println("当前月的第一天"+firstDayOfMonth);

//获取本月最后一天
LocalDate lastDayOfMonth = today.with(TemporalAdjusters.lastDayOfMonth());
System.out.println("当前月的最后一天"+lastDayOfMonth);
//获取下一天
LocalDate nextDay = lastDayOfMonth.plusDays(1);
System.out.println("下一天(次月第一天)"+nextDay);
//获取当年最后一天
LocalDate lastday = today.with(TemporalAdjusters.lastDayOfYear());
System.out.println("当前月第一天:"+lastday);
//获取当年最后一个周日
LocalDate lastSundayOfThisYear = lastday.with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
System.out.println("当年最后一个周日"+lastSundayOfThisYear);
相关推荐
许野平14 分钟前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
也无晴也无风雨18 分钟前
在JS中, 0 == [0] 吗
开发语言·javascript
狂奔solar26 分钟前
yelp数据集上识别潜在的热门商家
开发语言·python
duration~29 分钟前
Maven随笔
java·maven
zmgst33 分钟前
canal1.1.7使用canal-adapter进行mysql同步数据
java·数据库·mysql
跃ZHD42 分钟前
前后端分离,Jackson,Long精度丢失
java
blammmp1 小时前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧1 小时前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
暗黑起源喵1 小时前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong1 小时前
Java反射
java·开发语言·反射