当前位置: 首页 > news >正文

Java 8特性(一)

目录

 

一、Lambda表达式

1、语法格式:

(1)接口名 对象名=(参数类型1参数名1,....参数类型n 参数名n)->{方法体;}

(2)参数类型h 参数名n:接口中抽象方法的参数项

(3)->:表示连接操作

(4){}:存放重写的方法体内容。可以理解为对抽象方法的覆盖

2、简写格式:

(1)参数类型可以简写

(2)小括号,当参数只有1个时,可以省略  

(3){}、return、; 同时进行省略

二、函数式接口

(1)Supplier接口 --供给型接口:

(2)Consumer接口 --消费型接口:

(3)Function接口 --转换型接口:

(4)Predicate接口--断言型接口:

(5)Comparator接口--比较器接口:

三、Stream流:

1、使用Stream流处理集合数据:

2、获取Stream流的两种方式:

Collection集合提供了 default Stream stream()获取流;

Stream接口的静态方法 of 可以获取对应的流。

3、Stream 流的常用方法:

(1)forEach() :遍历流中的元素

(2)count():Stream 流提供的count方法,统计其中的元素个数

(3)filter(): 用于锅炉数据,返回符合条件的数据

(4)limit()方法: 可以对流的元素进行截取前几个

(5)skip()方法: 跳过前几个元素,可以使用skip方法获取一个截取之后的新的集合

(6)map() 可以将一种类型转换成另一种类型

(7)sorted()方法可以默认泛型排序,也可以自定义排序规则

(8)match()如果需要判断数据是否匹配指定的条件。可以使用match方法

(8.1)allMatch()判断所有元素是否满足条件

(8.2)anyMatch() 只要有一个满足条件就返回true

(8.3)noneMatch()所有的元素都不满足,返回true 

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

Collectors.toList():转成List集合

Collectors.toSet():转成Set集合

Collectors.toMap():转成map集合

Collectors.groupingBy() :可以按照指定内容进行统计

Collectors.mapping():将一种数据类型的集合映射成另一种数据类型

4、Parallel Stream 并行流:


 

一、Lambda表达式

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

1、语法格式:

(1)接口名 对象名=(参数类型1参数名1,....参数类型n 参数名n)->{方法体;}

(2)参数类型h 参数名n:接口中抽象方法的参数项

(3)->:表示连接操作

(4){}:存放重写的方法体内容。可以理解为对抽象方法的覆盖

2、简写格式:

(1)参数类型可以简写

(2)小括号,当参数只有1个时,可以省略  

(3){}、return、; 同时进行省略

package com.yuan.lambda;public class Demo02 {public static void main(String[] args) {swim(new ISwim() {@Overridepublic void swimming() {System.out.println("Frog蛙泳");}});swim(()-> System.out.println("Duck蛙泳"));}public static void swim(ISwim s1){System.out.println("进入swim方法");s1.swimming();System.out.println("结束swim方法");}
}
interface ISwim{void swimming();
}

    二、函数式接口

               在 Java 8 中专门有一个包放函数式接口java.util.function,该包下的所有接口都有 @FunctionalInterface 注解,提供函数式编程方式。下面是最常用的几个接口。

    (1)Supplier接口 --供给型接口:

    @FunctionalInterface
    public interface Supplier<T> {
        public abstract T get();
    }

    java.util.function.Supplier<T> 接口 - 方法没有参数,有返回值--供给型接口。

    它意味着"供给" , 对应的Lambda表达式需要“对外提供”一个符合泛型类型的对象数据。
    供给型接口,通过Supplier接口中的get方法可以得到一个值,无参有返回的接口。

    //案例
    public class Demo01 {public static void main(String[] args) {System.out.println("进入到main方法中");printMax(()->{System.out.println("进入到get方法中");Integer[] array={1,2,3,4,5};Integer number= Collections.max(Arrays.asList(array));System.out.println("在get中找到最大值了"+number);return number;});Integer number = number(() -> {while(true) {int number1 = (int) (Math.random() * 11 + 10);if((number1&1)==0){return number1;}}});System.out.println("随机数为:"+number);}public static Integer number(Supplier<Integer> sup){Integer ranNum=sup.get();return ranNum;}public static void printMax(Supplier<Integer> sup){System.out.println("机内到printMax方法中");Integer number=sup.get();System.out.println("printMax要打印的sup获取的最大值"+number);}
    }
    

    (2)Consumer接口 --消费型接口:

    @FunctionalInterface 
    public interface Consumer<T> { 
        public abstract void accept(T t); 

    java.util.function.Consumer<T> 接口则正好相反 --方法有参数,没有返回值,它不是生产一个数据,而是消费一个数据,其数据类型由泛型参数决定。 --消费型接口

    Consumer消费型接口,可以拿到accept方法参数传递过来的数据进行处理, 有参无返回的接口。

    //案例
    public class Demo02 {public static void main(String[] args) {//转大写caseLetter(t->System.out.println(t.toUpperCase()),"HelloWorld");//转小写caseLetter(t->System.out.println(t.toLowerCase()),"HelloWorld");//先转大写,再转小写caseLetters(t->System.out.println(t.toUpperCase()),t->System.out.println(t.toLowerCase()),"HelloWorld");}public static void caseLetter(Consumer<String> consumer,String str){consumer.accept(str);}public static void caseLetters(Consumer<String> consumer1,Consumer<String> consumer2,String str){consumer1.andThen(consumer2).accept(str);}
    }
    

    (3)Function接口 --转换型接口:

    @FunctionalInterface 
    public interface Function<T, R> { 
        public abstract R apply(T t); 

    java.util.function.Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据,前者称为前置条件, 后者称为后置条件。有参数有返回值。----- 此方法接收一个参数,加工处理成另一种,称为转换型接口
    Function转换型接口,对apply方法传入的T类型数据进行处理,返回R类型的结果,有参有返回的接口。使用的场景 例如:将 String类型转换为 Integer类型。

    //案例
    public class Demo03 {public static void main(String[] args) {// 1.获取字符串的长度Function<String, Integer> f1 = s1 -> s1.length();test(f1, "1234abc");// 2.截取字符串的前3位,将其转换成数字test(s1 -> Integer.parseInt(s1.substring(0, 3)), "123aneii");test(s1 -> s1.length(), len -> new int[len], "abc");}public static void test(Function<String, Integer> function, String str) {Integer number = function.apply(str);System.out.println(number);}public static void test(Function<String, Integer> f1,Function<Integer, int[]> f2,String str) {int[] arr = f1.andThen(f2).apply(str);System.out.println(Arrays.toString(arr));}
    }

    (4)Predicate接口--断言型接口:

    @FunctionalInterface 
    public interface Predicate<T> { 
        public abstract boolean test(T t); 

    Predicate接口用于做判断,返回boolean类型的值

    有时候我们需要对某种类型的数据进行判断,从而得到一个boolean值结果。这时可以使用

    java.util.function.Predicate<T> 接口。------接收一个参数,返回一个boolean类型的值,称为判断型接口

    //案例
    public class Demo04 {public static void main(String[] args) {int number = new Random().nextInt(200);// 1.判断此数字是否大于等于100method(num -> num >= 100, number);// 2.判断此数字是否是偶数method(num -> (num & 1) == 0, number);methods(num -> num >= 100, num -> (num & 1) == 0, number);}public static void method(Predicate<Integer> p, Integer num) {boolean b = p.test(num);System.out.println("数字num:" + num + "判断后的结果为:" + b);}public static void methods(Predicate<Integer> p1, Predicate<Integer> p2, Integer num) {boolean b = p1.and(p2).test(num);System.out.println("数字num:" + num + "是否大于100并且为偶数:" + b);boolean b1 = p1.or(p2).test(num);System.out.println("数字num:" + num + "是否大于100或者为偶数:" + b1);boolean b2 = p1.negate().test(num);System.out.println("数字num:" + num + "是否不大于100:" + b2);boolean b3 = p2.negate().test(num);System.out.println("数字num:" + num + "是否不为偶数:" + b3);}
    }

    (5)Comparator接口--比较器接口:

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

    
    List<String> langList = Arrays.asList("Basic", "QBasic","HTML", "c", "c++", "PowerBuilder", "go", "Visual Basic", "c#","java");// 按照ASCII码比较
    Comparator<String> comparator1 = (s1, s2) -> {return s1.compareTo(s2);
    };// 按照长度比较
    Comparator<String> comparator2 = (s1, s2) -> {return s1.length() - s2.length();
    };// 先比较长度,再比较ASCII码
    Comparator<String> comparator3 = comparator2.thenComparing(comparator1);// 在comparator3的基础上,反转条件
    Comparator<String> comparator4 = comparator2.reversed();// 按照指定Comparator,进行排序
    langList.sort(comparator2);

    三、Stream流:

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

    1、使用Stream流处理集合数据:

    当我们需要对集合中的元素进行操作的时候,除了必需的添加、删除、获取外,最典型的就是集合遍历。我们来体验 集合操作数据的弊端,需求如下:

    package com.yuan.stream;import java.util.ArrayList;
    import java.util.Collections;public class Demo01 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");// 1.拿到所有姓张的ArrayList<String> zhanglist = new ArrayList<String>();for (String string : list) {if (string.startsWith("张")) {zhanglist.add(string);}}ArrayList<String> threeList = new ArrayList<String>();// 2.拿到名字长度为3的字for (String string : zhanglist) {if (string.length() == 3) {threeList.add(string);}}System.out.println(threeList);//使用stream 流list.stream().filter(s1->s1.charAt(0)=='张').filter(s1->s1.length()==3).forEach(s1-> System.out.println(s1));}
    }
    

    2、获取Stream流的两种方式:

    java.util.stream.Stream<T>是JDK 8新加入的流接口。 获取一个流非常简单,有以下几种常用的方式:

    1. Collection集合提供了 default Stream<E> stream()获取流;

    2. Stream接口的静态方法 of 可以获取对应的流。

    package com.yuan.stream;import java.sql.Array;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.List;
    import java.util.stream.Stream;//Stream 流的获取方式
    //1、Collection 集合提供了default Stream<E>  stream()获取流
    //2、Stream 接口的静态方法of可以获取对应的流
    public class Demo02 {public static void main(String[] args) {//方式一: Stream 的静态方法ofStream<String> s1 = Stream.of("aa", "bb", "cc");System.out.println(s1);String[] arr={"aa", "bb", "cc"};Stream<String> s2 = (Stream<String>) Stream.of(arr);System.out.println(s2);int[] numbers={1,2,3,4};Stream<int[]> s3 = Stream.of(numbers);System.out.println(s3);//方式二:  Collection 接口中Stream方法List<String> list = Arrays.asList("aa", "bb", "cc");Stream<String> s4 = list.stream();System.out.println(s4);HashSet<String> set = new HashSet<>(list);Stream<String> s5 = set.stream();System.out.println(s5);HashMap<String, Integer> map = new HashMap<>();System.out.println(map.entrySet().stream());}
    }
    

    3、Stream 流的常用方法:

    Stream流模型的操作很丰富,这里介绍一些常用的API。

    这些方法可以被分成两种:

    终结方法:返回值类型不再是 Stream类型的方法,不再支持链式调用。本小节中,终结方法包括 count和 forEach 方法。

    非终结方法:返回值类型仍然是 Stream类型的方法,支持链式调用。(除了终结方法外,其余方法均为非终结 方法。)

    (1)forEach() :遍历流中的元素

    (2)count():Stream 流提供的count方法,统计其中的元素个数

    (3)filter(): 用于锅炉数据,返回符合条件的数据

    (4)limit()方法: 可以对流的元素进行截取前几个

    (5)skip()方法: 跳过前几个元素,可以使用skip方法获取一个截取之后的新的集合

    package com.yuan.method;import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.List;
    import java.util.stream.Stream;public class Demo01 {public static void main(String[] args) {List<String> list=new ArrayList<>();Collections.addAll(list,"迪丽热巴","陶白白","吴磊","易烊千玺","刘亦菲");//1、forEach() 获取流,遍历集合中的元素Stream<String> s1 = list.stream();s1.forEach(System.out::println);//2、count():Stream 流提供的count方法,统计其中的元素个数Stream<String> s2 = list.stream();long count = s2.count();System.out.println(count);//3、filter(): 用于锅炉数据,返回符合条件的数据list.stream().filter(str->str.length()==3).forEach(System.out::println);System.out.println("=========================");//4、limit()方法: 可以对流的元素进行截取前几个list.stream().limit(2).forEach(str-> System.out.print(str+" "));System.out.println();System.out.println("===============");//5、skip()方法: 跳过前几个元素,可以使用skip方法获取一个截取之后的新的集合list.stream().skip(0).forEach(str-> System.out.print(str+" "));}
    }
    

    (6)map() 可以将一种类型转换成另一种类型

    (7)sorted()方法可以默认泛型排序,也可以自定义排序规则

    (8)match()如果需要判断数据是否匹配指定的条件。可以使用match方法

    (8.1)allMatch()判断所有元素是否满足条件

    (8.2)anyMatch() 只要有一个满足条件就返回true

    (8.3)noneMatch()所有的元素都不满足,返回true 

    package com.yuan.method;import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.stream.Stream;public class Demo02 {public static void main(String[] args) {ArrayList<String> list=new ArrayList<>(Arrays.asList("32","22","45","11","33"));Stream<String> s1 = list.stream();//6、map() 可以将一种类型转换成另一种类型Stream<Integer> s2 = s1.map(str -> Integer.parseInt(str));
    //        s2.forEach(number-> System.out.println(number));System.out.println("==========sorted=========");//如果满要将数据排序、可以使用 sorted方法//使用泛型类型的默认排序规则排序// s2.sorted().forEach(number-> System.out.println(number))//使用自定义的Comparator比较规则排序s2.sorted((a,b)->b-a).forEach(number-> System.out.println(number));System.out.println("==========distinct=========");Stream.of(1,3,2,1,3,4,5,6).distinct().forEach(System.out::println);System.out.println("==========match=========");//如果需要哦按段数据是否匹配指定的条件。可以使用match方法//判断所有的元素是否满足条件boolean b1 = Stream.of(1, 3, 2, 1, 3, 4, 5, 6).allMatch(number -> number > 0);System.out.println("allmatch: "+b1);//只要有一个满足条件就返回true   ||  orboolean b2 = Stream.of(1, 3, 2, 1, 3, 4, 5, 6).anyMatch(number -> number > 5);System.out.println("anymatch: "+b2);//所有的元素都不匹配,返回trueboolean b3 = Stream.of(1, 3, 2, 1, 3, 4, 5, 6).noneMatch(number -> number > 100);System.out.println("nonematch: "+b3);}
    }
    

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

    Collectors.toList():转成List集合

    Collectors.toSet():转成Set集合

    Collectors.toMap():转成map集合

    Collectors.groupingBy() :可以按照指定内容进行统计

    Collectors.mapping():将一种数据类型的集合映射成另一种数据类型

    package com.yuan.method;import java.util.*;
    import java.util.stream.Collectors;public class Demo03 {public static void main(String[] args) {List<String> langList = Arrays.asList("abc", "deft", "gbhk", "bac", "fgh");//将结果过滤,收集至List集合List<String> list = langList.stream().filter(str -> str.toUpperCase().contains("B")).collect(Collectors.toList());System.out.println(list);//将过滤结果收集到Set集合Set<String> set = langList.stream().filter(str -> str.toUpperCase().contains("B")).collect(Collectors.toSet());System.out.println(set);//将过滤结果收集到map集合Map<String, Integer> map = langList.stream().distinct().filter(s -> s.toUpperCase().contains("B")).collect(Collectors.toMap(s -> s, s -> s.length()));System.out.println(map);//按照字符串的长度统计Map<Integer, List<String>> groupMap = langList.stream().collect(Collectors.groupingBy(str -> str.length()));System.out.println(groupMap);//按照字符串长度转成集合List<Integer> mappingList = langList.stream().collect(Collectors.mapping(str -> str.length(), Collectors.toList()));System.out.println(mappingList);}
    }
    

    4、Parallel Stream 并行流:

    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 t0 = System.nanoTime();//返回豪微秒
    long count = values.stream().sorted().count();
    System.out.println(count);

    long t1 = System.nanoTime();

    long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
    System.out.println(String.format("串行排序,耗时共计: %d 毫秒", millis));

    //并行排序

    long t0 = System.nanoTime();

    long count = values.parallelStream().sorted().count();
    System.out.println(count);

    long t1 = System.nanoTime();

    long millis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
    System.out.println(String.format("并行排序,耗时共计: %d 毫秒", millis));

    并行的执行效率高,但是不安全,在使用时要注意线程安全,

     

    http://www.dtcms.com/a/322820.html

    相关文章:

  • 新手向:Python开发简易待办事项应用
  • 顺风车软件系统架构分析
  • 大语言模型提示工程与应用:ChatGPT提示工程技术指南
  • PDF编辑工具,免费OCR识别表单
  • ST语法介绍
  • GloVe词向量:原理详解及用python进行训练和应用GloVe
  • 【第四章:大模型(LLM)】05.LLM实战: 实现GPT2-(1)文本token到Embedding的代码实现
  • 【数据分享】各省农业土地流转率(2010-2023)
  • Easysearch 冷热架构实战
  • 分治-快排-面试题 17.14.最小k个数-力扣(LeetCode)
  • Redhat Linux 9.6 配置本地 yum 源
  • 【数据结构入门】栈和队列
  • 网盘短剧资源转存项目源码 支持垮克 带后台 附教程
  • Kafka服务端NIO操作原理解析(二)
  • MX 播放器:安卓设备上的全能视频播放器
  • 【解决方法】华为电脑的亮度调节失灵
  • 本地部署接入 whisper + ollama qwen3:14b 总结字幕
  • 服务机器人选择屏幕的逻辑
  • 微软推出革命性AI安全工具Project IRE,重塑网络安全防御新范式
  • Orange的运维学习日记--37.iSCSI详解与服务部署
  • FreeRTOS学习笔记:任务通知和软件定时器
  • jQuery 零基础学习第一天
  • 数据结构—二叉树及gdb的应用
  • 【贪心】P4873 [USACO14DEC] Cow Jog G|省选-
  • MBR分区nvme固态硬盘安装win7--非UEFI启动和GPT分区
  • llm本地部署+web访问+交互
  • Oracle字段操作
  • [TryHackMe]Challenges---Game Zone游戏区
  • 力扣热题100-----118.杨辉三角
  • Kettle ETL 工具存在的问题以及替代方案的探索