首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JAVA零基础小白入门上手教程之day22-JDK新特性

JAVA零基础小白入门上手教程之day22-JDK新特性

作者头像
张哥编程
发布于 2024-12-13 07:46:30
发布于 2024-12-13 07:46:30
7000
代码可运行
举报
文章被收录于专栏:云计算linux云计算linux
运行总次数:0
代码可运行

接口中的新特性

接口我们之前已经学过了,那么接口中内部主要就是封装了方法,包含抽象方法(JDK 7及以前),默认方法和静态方法(JDK 8),私有方法 (JDK 9)。

接口中可以有的内容

JDK1.7之前

抽象方法 常量

JDK1.8

默认方法 静态方法

JDK1.9

私有方法

接口默认方法的定义和使用

默认方法:使用 default 修饰,不可省略,供子类调用或者子类重写。

默认方法定义格式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public default 返回值类型  方法的名称(参数列表){
    方法体
}
默认方法的好处

接口的默认方法,实现类可以不用重写,默认方法可以用于接口升级 /** * @Auther: yanqi * @Desc 实现类没有没重写默认方法呢? * 接口中的抽象方法是必须要重写(实现) * 接口中的默认方法,不用重写,也可以手动重写,你默认方法存在的意义? * * 如果今后项目代码已以经写好,后期可能要扩展,接口中加新的方法(功能),如果你加抽象方法(功能) * 所有的实现类有影响,所以针对以上后期可能要扩展功能的话,代码的维护性比较差,出现了默认方法 */

定义接口
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface LiveAble {
    //接口的默认方法
    public default void fly(){ 
        System.out.println("天上飞"); 
    } 
}
定义实现类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Animal implements LiveAble {    
    // default 可以选择是否重写,也可以根据实际需求进行重写
    /*
    	@Override
   		public void fly() {
        	System.out.println("自由自在的飞");   
        }
    */
}
定义测试类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class InterfaceDemo {
    public static void main(String[] args) {       
        // 创建子类对象 
        Animal a = new Animal();
        // 调用默认方法
        a.fly();
    }
}

接口静态方法的定义和使用

静态方法:使用 static 修饰,供接口直接调用。 静态与.class文件相关,只能使用接口名调用,不可以通过实现类的类名或者实现类的对象调用

静态方法定义格式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static 返回值类型 方法名称(参数列表){
    方法体
}
静态方法使用
定义接口
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface LiveAble {
    //静态方法
    public static void show2(){
        System.out.println("静态方法-show2");
    }
}
定义实现类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Animal implements LiveAble {    
  // 无法重写静态方法
}
定义测试类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class InterfaceDemo {
    public static void main(String[] args) {
        //无法调用
        // LiveAble l = new LiveAbleImpl();
        // l.show2();
        
        //接口名.静态方法(参数列表)
       LiveAble.show2();
    } 
}

接口私有方法的定义和使用

如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法 去调用。从设计的角度讲,私有的方法是对默认方法和静态方法的辅助。

私有方法分类
  • 普通私有方法

只有默认方法可以调用。

  • 私有静态方法

默认方法和静态方法可以调用。

代码演示
私有方法
  • 定义接口
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface MyInterfacePrivateA {
	//默认方法
    public default void methodDefault1() {
        System.out.println("默认方法1");
        methodCommon();
    }

    //默认方法
    public default void methodDefault2() {
        System.out.println("默认方法2");
        methodCommon();
    }

    //普通-私有方法
    private void methodCommon() {
        System.out.println("AAA");
        System.out.println("BBB");
        System.out.println("CCC");
    }

}
  • 私有静态方法
  • 定义接口
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface MyInterfacePrivateB {
    //静态方法
    public static void methodStatic1() {
        System.out.println("静态方法1");
        methodStaticCommon();
    }

    //静态方法
    public static void methodStatic2() {
        System.out.println("静态方法2");
        methodStaticCommon();
    }

    //私有-静态方法
    private static void methodStaticCommon() {
        System.out.println("AAA");
        System.out.println("BBB");
        System.out.println("CCC");
    }
}

私有方法主要解决的问题是:

默认方法和static方法代码重复的问题,private方法可作为抽取共性

Lambda表达式

什么是Lambda

Lambda 表达式是 Java8 新增的重要特性,Lambda 使 Java 具有了类似函数式编程的风格,其实 Lambda 表达式也是一个 “语法糖”,其实质也是由编译器根据表达式推断最终生成原始语法的字节码方式。

JAVA零基础小白入门上手教程之day22-JDK新特性_java
JAVA零基础小白入门上手教程之day22-JDK新特性_java

面象对象思想:

做一件事情,找一个能解决这个事情的对象,调用这个对象的方法,完成事情

函数式编程思想:

只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程

函数式思想

函数式思想则尽量忽略面向对象的复杂语法:“强调做什么,而不是以什么形式去做” 而我们要学习的Lambda表达式就是函数式思想的体现

函数式接口

函数式接口在java中指的是:有且仅有一个抽象方法的接口 当然接口中可以有其他的方法(默认方法,静态方法,私有方法) 函数式接口的使用: 一般用作方法的参数和返回值类型

体验Lambda

案例需求

启动一个线程,在控制台输出一句话:多线程程序启动了

实现步骤
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- 定义一个类MyRunnable实现Runnable接口,重写run()方法
- 创建MyRunnable类的对象
- 创建Thread类的对象,把MyRunnable的对象作为构造参数传递
- 启动线程
代码实现
定义线程类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("多线程程序启动了");
    }
}
new Thread 方式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//方式一
MyRunnable my = new MyRunnable();
Thread t = new Thread(my);
t.start();
匿名内部类方式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//方式二
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("多线程程序启动了");
    }
}).start();
Lambda实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//方式三
new Thread( () -> {
    System.out.println("多线程程序启动了");
} ).start();

Lambda标准格式

格式

(形式参数) -> { 代码块 }

格式解析
  • 形式参数:如果有多个参数,参数之间用逗号隔开;如果没有参数,留空即可
  • ->:由英文中画线和大于符号组成,固定写法。代表指向动作
  • 代码块:是我们具体要做的事情,也就是以前我们写的方法体内容

Lambda表达式练习

Lambda表达式使用前提

  • 有一个接口
  • 接口中有且仅有一个抽象方法
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * @Auther: yanqi
 * @Desc: 函数式接口在java中指的是:有且仅有一个抽象方法的接口
 *        当然接口中可以有其他的方法(默认方法,静态方法,私有方法)
          **函数式接口的使用: 一般用作方法的参数和返回值类型**
 *
 *          @FunctionalInterface
 *          作用:可以检测接口是不是一个函数式接口
 *              是:编译成功
 *              否:编译失败(接口中没有抽象方法,抽象方法多于1个)
 */

@FunctionalInterface
public interface LambdaInter{

    //定义一个抽象方法
    public abstract void method();

    // public abstract  void method2();//编译不通过,只能有一个抽象方法

}
抽象方法是无参无返回值
实现步骤

  • 定义一个接口(Eatable),里面定义一个抽象方法:void eat();
  • 定义一个测试类(EatableDemo),在测试类中提供两个方法
  • 一个方法是:useEatable(Eatable e)
  • 一个方法是主方法,在主方法中调用useEatable方法
代码实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//接口
public interface Eatable {
    //抽象方法无参无返回值
    void eat();
}
//实现类
public class EatableImpl implements Eatable {
    @Override
    public void eat() {
        System.out.println("一天一苹果,医生远离我");
    }
}

/** 
 * 测试类
 * @Auther: yanqi
 * @Desc **函数式接口的使用: 一般用作方法的参数和返回值类型**
 */
public class EatableDemo {
    public static void main(String[] args) {
        //方式一:匿名内部类
        useEatable(new Eatable() {
            @Override
            public void eat() {
                System.out.println("方式一:匿名内部类");
            }
        });

        //方式二:Lambda表达式
        //()表示eat()方法的参数列表,{}内部表示方法体
        useEatable(()->{
            System.out.println("方式二:Lambda表达式");
        });
    }

    //定义一个方法,参数用我们定义的函数式接口
    private static void useEatable(Eatable e) {
        e.eat();
    }

}
抽象方法是有参无返回值
实现步骤

  • 定义一个接口(Flyable),里面定义一个抽象方法:void fly(String s);
  • 定义一个测试类(FlyableDemo),在测试类中提供两个方法
  • 一个方法是:useFlyable(Flyable f)
  • 一个方法是主方法,在主方法中调用useFlyable方法
代码实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface Flyable {
    //抽象方法是有参无返回值
    void fly(String s);
}

public class FlyableDemo {
    public static void main(String[] args) {
   
        //方式一:匿名内部类
        useFlyable(new Flyable() {
            @Override
            public void fly(String s) {
                System.out.println(s);
                System.out.println("飞机自驾游");
            }
        });
        System.out.println("--------");

        //方式二:Lambda表达式
        //useFlyable((String s) -> {
        useFlyable((s) -> { //类型也可以省略,lambda表达式会自己行判断类型   
            System.out.println(s);
            System.out.println("飞机自驾游");
        });

    }

    private static void useFlyable(Flyable f) {
        f.fly("风和日丽,晴空万里");
    }
}
抽象方法是有参有返回值
操作步骤

  • 定义一个接口(Addable),里面定义一个抽象方法:int add(int x,int y);
  • 定义一个测试类(AddableDemo),在测试类中提供两个方法
  • 一个方法是:useAddable(Addable a)
  • 一个方法是主方法,在主方法中调用useAddable方法
代码实现
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface Addable {
    // 抽象方法是有参有返回值
    int add(int x,int y);
}

public class AddableDemo {
    public static void main(String[] args) {
        //方式一:匿名内部类
        useAddable(new Addable() {
            @Override
            public int add(int x, int y) {
                return x+y;
            }
        });
        
        //方式二:lambda
        useAddable((int x,int y) -> {
            return x + y;
        });
        //可以省略类型
        useAddable((x,y)->{
           return x+y;
        });
        //如果代码块的语句只有一条,可以省略大括号和分号,和return关键字,不建议
        useAddable((x,y)->
             x+y
        );

    }

    private static void useAddable(Addable a) {
        int sum = a.add(10, 20);
        System.out.println(sum);
    }
}
Lambda表达式的省略模式

省略规则

  • 参数类型可以省略。但是有多个参数的情况下,不能只省略一个
  • 如果参数有且仅有一个,那么小括号可以省略
  • 如果代码块的语句只有一条,可以省略大括号和分号,和return关键字

代码演示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface Addable {
    int add(int x, int y);
}

public interface Flyable {
    void fly(String s);
}

public class LambdaDemo {
    public static void main(String[] args) {
//        useAddable((int x,int y) -> {
//            return x + y;
//        });
        //参数的类型可以省略
        useAddable((x, y) -> {
            return x + y;
        });

//        useFlyable((String s) -> {
//            System.out.println(s);
//        });
        //如果参数有且仅有一个,那么小括号可以省略
//        useFlyable(s -> {
//            System.out.println(s);
//        });

        //如果代码块的语句只有一条,可以省略大括号和分号
        useFlyable(s -> System.out.println(s));

        //如果代码块的语句只有一条,可以省略大括号和分号,如果有return,return也要省略掉
        useAddable((x, y) -> x + y);
    }

    private static void useFlyable(Flyable f) {
        f.fly("风和日丽,晴空万里");
    }

    private static void useAddable(Addable a) {
        int sum = a.add(10, 20);
        System.out.println(sum);
    }
}
Lambda表达式的注意事项
  • 使用Lambda必须要有接口,并且要求接口中有且仅有一个抽象方法
  • 必须有上下文环境,才能推导出Lambda对应的接口
  • 根据局部变量的赋值得知Lambda对应的接口

Runnable r = () -> System.out.println(“Lambda表达式”);

  • 根据调用方法的参数得知Lambda对应的接口

new Thread(() -> System.out.println(“Lambda表达式”)).start();

lambda表达式主要用于替换以前广泛使用的内部匿名类,使代码更简洁

Stream流

它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。

Stream(流)是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

体验Stream流

案例需求

按照下面的要求完成集合的创建和遍历

  • 创建一个集合,存储多个字符串元素
  • 把集合中所有以"张"开头的元素存储到一个新的集合
  • 把"张"开头的集合中的长度为3的元素存储到一个新的集合
  • 遍历上一步得到的集合
  • 原始方式示例代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamDemo {
    public static void main(String[] args) {
        //1、创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<>();
        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //2、把集合中所有以"张"开头的元素存储到一个新的集合
        ArrayList<String> zhangList = new ArrayList<>();
        for(String s : list) {
            if(s.startsWith("张")) {
                zhangList.add(s);
            }
        }
        System.out.println(zhangList);//[张曼玉, 张无忌]

        //3、把"张"开头的集合中的长度为3的元素存储到一个新的集合
        ArrayList<String> threeList = new ArrayList<>();
        for(String s : zhangList) {
            if(s.length() == 3) {
                threeList.add(s);
            }
        }
        System.out.println(threeList);//张曼玉 张无忌

        //4、遍历上一步得到的集合
        for(String s : threeList) {
            System.out.println(s);
        }
    }
}
使用Stream流示例代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamDemo {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //Stream流来改进  s表示的list集合的String类型
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
        
        System.out.println("========遍历集合========");
        list.forEach(System.out::println);
        
        System.out.println("========遍历数组========");
        //定义数组
         String[] s = {"hello","world","java","yiyan"};
        //数组需要先转成流,才能使用
        Arrays.stream(s).forEach(System.out::println);
    }
}

Stream流的好处

  • 直接阅读代码的字面意思即可完美展示无关逻辑方式的语义:获取流、过滤姓张、过滤长度为3、逐一打印
  • Stream流把真正的函数式编程风格引入到Java中

Stream流的思想

JAVA零基础小白入门上手教程之day22-JDK新特性_java_02
JAVA零基础小白入门上手教程之day22-JDK新特性_java_02

获取Stream流的三种方式

Collection体系集合

使用默认方法stream()生成流, default Stream stream()

Map体系集合

把Map转成Set集合,间接的生成流

数组

通过Stream接口的静态方法of(T… values)生成流

3.3.2 代码演示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamDemo {
    public static void main(String[] args) {
        //Collection体系的集合可以使用默认方法stream()生成流
        List<String> list = new ArrayList<String>();
        Stream<String> listStream = list.stream();

        Set<String> set = new HashSet<String>();
        Stream<String> setStream = set.stream();

        //Map体系的集合间接的生成流
        Map<String,Integer> map = new HashMap<String, Integer>();
        Stream<String> keyStream = map.keySet().stream();
        Stream<Integer> valueStream = map.values().stream();
        Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();

        //数组可以通过Stream接口的静态方法of(T... values)生成流
        String[] strArray = {"hello","world","java"};
        Arrays.stream(strArray).forEach(System.out::println);
        Stream<String> strArrayStream = Stream.of(strArray);
        Stream<String> strArrayStream2 = Stream.of("hello", "world", "java");
        Stream<Integer> intStream = Stream.of(10, 20, 30);
    }
}

Stream流中间操作方法

概念

中间操作的意思是,执行完此方法之后,Stream流依然可以继续执行其他操作。

  • 一个中间操作链,对数据源的数据进行处理。
  • 多个中间操作可以连接起来形成一个流水线

3.4.2 常见方法

方法名

说明

Stream filter(Predicate predicate)

用于对流中的数据进行过滤

Stream limit(long maxSize)

返回此流中的元素组成的流,截取前指定参数个数的数据

Stream skip(long n)

跳过指定参数个数的数据,返回由该流的剩余元素组成的流

static Stream concat(Stream a, Stream b)

合并a和b两个流为一个流

Stream distinct()

返回由该流的不同元素(根据Object.equals(Object) )组成的流

Stream sorted()

返回由此流的元素组成的流,根据自然顺序排序

Stream map(Function mapper)

返回由给定函数应用于此流的元素的结果组成的流

IntStream mapToInt(ToIntFunction mapper)

返回一个IntStream其中包含将给定函数应用于此流的元素的结果

filter方法

用于对流中的数据进行过滤

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamDemo01 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:把list集合中以张开头的元素在控制台输出
        list.stream().filter(s -> s.startsWith("张")).forEach(System.out::println);
        System.out.println("--------");

        //需求2:把list集合中长度为3的元素在控制台输出
        list.stream().filter(s -> s.length() == 3).forEach(System.out::println);
        System.out.println("--------");

        //需求3:把list集合中以张开头的,长度为3的元素在控制台输出
        list.stream().filter(s -> s.startsWith("张")).filter(s -> s.length() == 3).forEach(System.out::println);
                      
        //简化for循环
        list.forEach(System.out::println);
    }
}

limit&skip

返回此流中的元素组成的流,截取前指定参数个数和跳过指定个数的数据

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamDemo02 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:取前3个数据在控制台输出
        list.stream().limit(3).forEach(System.out::println);
        System.out.println("--------");

        //需求2:跳过3个元素,把剩下的元素在控制台输出
        list.stream().skip(3).forEach(System.out::println);
        System.out.println("--------");

        //需求3:跳过2个元素,把剩下的元素中前2个在控制台输出
        list.stream().skip(2).limit(2).forEach(System.out::println);

    }
}

concat&distinct

concat:将两个流合并成为一个流 distinct:由该流的不同元素(根据Object.equals(Object) )组成的流

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamDemo03 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:取前4个数据组成一个流
        Stream<String> s1 = list.stream().limit(4);
        s1.forEach(System.out::println);

        //需求2:跳过2个数据组成一个流
        Stream<String> s2 = list.stream().skip(2);
        s2.forEach(System.out::println);

        //需求3:合并需求1和需求2得到的流,并把结果在控制台输出
	   //Stream.concat(s1,s2).forEach(System.out::println);

        //需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复
        Stream.concat(s1,s2).distinct().forEach(System.out::println);
    }
}

sorted

由此流的元素组成的流,根据自然顺序排序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamDemo04 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("linqingxia");
        list.add("zhangmanyu");
        list.add("wangzuxian");
        list.add("liuyan");
        list.add("zhangmin");
        list.add("zhangwuji");

        //需求1:按照字母顺序把数据在控制台输出
		list.stream().sorted().forEach(System.out::println);
    }
}

map&mapToInt

map() 返回由给定函数应用于此流的元素的结果组成的流(将流中的元素映射到另一个流中) mapToInt 计算流中的数据并返回结果

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamDemo05 {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("10");
        list.add("20");
        list.add("30");
        list.add("40");
        list.add("50");

        //需求:将集合中的字符串数据转换为整数之后在控制台输出
       list.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println);
       list.stream().map(Integer::parseInt).forEach(System.out::println);

        //int sum() 返回此流中元素的总和
        int result = list.stream().mapToInt(Integer::parseInt).sum();
        System.out.println(result);
    }
}

Stream流终结操作方法

概念

终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作。 一个终止操作,执行中间操作链,并产生结果。 这是Stream操作中的最后一步,终止操作,终止操作会从流的流水线生成结果 例如:List、Integer,甚至是 void 。

相关方法

方法名

说明

void forEach(Consumer action)

对此流的每个元素执行操作

long count()

返回此流中的元素数

代码演示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamDemo {
    public static void main(String[] args) {
        //创建一个集合,存储多个字符串元素
        ArrayList<String> list = new ArrayList<String>();

        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");
        list.add("张敏");
        list.add("张无忌");

        //需求1:把集合中的元素在控制台输出,直接输出结果就不能返回stream对象了
//        list.stream().forEach(System.out::println);

        //需求2:统计集合中有几个以张开头的元素,并把统计结果在控制台输出
        long count = list.stream().filter(s -> s.startsWith("张")).count();
        System.out.println(count);
    }
}

Stream流综合练习

案例需求

现在有两个ArrayList集合,分别存储6名男演员名称和6名女演员名称,要求完成如下的操作

  • 男演员只要名字为3个字的前三人
  • 女演员只要姓林的,并且不要第一个
  • 把过滤后的男演员姓名和女演员姓名合并到一起
  • 把上一步操作后的元素作为构造方法的参数创建演员对象,遍历数据

演员类Actor已经提供,里面有一个成员变量,一个带参构造方法,以及成员变量对应的get/set方法

Actor类

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Actor {
    private String name;

    public Actor(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Actor{" +
                "name='" + name + '\'' +
                '}';
    }
}

案例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class StreamTest {
    public static void main(String[] args) {
        //创建集合
        ArrayList<String> manList = new ArrayList<String>();
        manList.add("周润发");
        manList.add("成龙");
        manList.add("刘德华");
        manList.add("吴京");
        manList.add("周星驰");
        manList.add("李连杰");


        ArrayList<String> womanList = new ArrayList<String>();
        womanList.add("林心如");
        womanList.add("张曼玉");
        womanList.add("林青霞");
        womanList.add("柳岩");
        womanList.add("林志玲");
        womanList.add("王祖贤");

        //男演员只要名字为3个字的前三人
        Stream<String> manStream = manList.stream().filter(s -> s.length() == 3).limit(3);

        //女演员只要姓林的,并且不要第一个
        Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);

        //把过滤后的男演员姓名和女演员姓名合并到一起
        Stream<String> stream = Stream.concat(manStream, womanStream);

        //使用map映射到一个新的对象中
        stream.map(s -> new Actor(s)).forEach(System.out::println);
        stream.map(Actor :: new).forEach(System.out::println);
        stream.map(Actor :: new).forEach(a -> System.out.println(a.getName()));

		//
        Stream.concat(manList.stream().filter(s -> s.length() == 3).limit(3),
                womanList.stream().filter(s -> s.startsWith("林")).skip(1)).map(Actor::new).
                forEach(p -> System.out.println(p.getName()));
    }
}

Stream流的收集操作

概念

对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中。

常用方法

方法名

说明

R collect(Collector collector)

把结果收集到集合中

  • 工具类Collectors提供了具体的收集方式

方法名

说明

public static Collectors toList()

把元素收集到List集合中

public static Collectors toSet()

把元素收集到Set集合中

public static Collectors toMap(Function keyMapper,Function valueMapper)

把元素收集到Map集合中

代码演示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class CollectDemo {
    public static void main(String[] args) {
        //创建List集合对象
        List<String> list = new ArrayList<String>();
        list.add("林青霞");
        list.add("张曼玉");
        list.add("王祖贤");
        list.add("柳岩");

        /*
        //需求1:得到名字为3个字的流
        Stream<String> listStream = list.stream().filter(s -> s.length() == 3);

        //需求2:把使用Stream流操作完毕的数据收集到List集合中并遍历
        List<String> names = listStream.collect(Collectors.toList());
	    names.stream().forEach(System.out::println);
        */

        //创建Set集合对象
        Set<Integer> set = new HashSet<Integer>();
        set.add(10);
        set.add(20);
        set.add(30);
        set.add(33);
        set.add(35);

        /*
        //需求3:得到年龄大于25的流
        Stream<Integer> setStream = set.stream().filter(age -> age > 25);

        //需求4:把使用Stream流操作完毕的数据收集到Set集合中并遍历
        Set<Integer> ages = setStream.collect(Collectors.toSet());
        ages.stream().forEach(System.out::println);
        */
        //定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组合而成
        String[] strArray = {"林青霞,30", "张曼玉,35", "王祖贤,33", "柳岩,25"};

        //需求5:得到字符串中年龄数据大于28的流
        Stream<String> arrayStream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28);

        //需求6:把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作键,年龄作值
        //toMap(林青霞,30)
        Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));

        Set<String> keySet = map.keySet();
        for (String key : keySet) {
            Integer value = map.get(key);
            System.out.println(key + "," + value);
        } 
       //要把map间接转成collection体系下的集合,可以使用stream流
        map.keySet().stream().forEach(System.out::println);
        map.values().stream().forEach(System.out::println);
        System.out.println("-----------------");
        map.keySet().stream().forEach(s -> System.out.println(s+":"+map.get(s )));
    }
}

流操作完毕的数据收集到Set集合中并遍历

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Set ages = setStream.collect(Collectors.toSet());
 ages.stream().forEach(System.out::println);
 */
 //定义一个字符串数组,每一个字符串数据由姓名数据和年龄数据组合而成
 String[] strArray = {“林青霞,30, “张曼玉,35, “王祖贤,33, “柳岩,25};//需求5:得到字符串中年龄数据大于28的流
    Stream<String> arrayStream = Stream.of(strArray).filter(s -> Integer.parseInt(s.split(",")[1]) > 28);

    //需求6:把使用Stream流操作完毕的数据收集到Map集合中并遍历,字符串中的姓名作键,年龄作值
    //toMap(林青霞,30)
    Map<String, Integer> map = arrayStream.collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));

    Set<String> keySet = map.keySet();
    for (String key : keySet) {
        Integer value = map.get(key);
        System.out.println(key + "," + value);
    } 
   //要把map间接转成collection体系下的集合,可以使用stream流
    map.keySet().stream().forEach(System.out::println);
    map.values().stream().forEach(System.out::println);
    System.out.println("-----------------");
    map.keySet().stream().forEach(s -> System.out.println(s+":"+map.get(s )));
}}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-04-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 接口中的新特性
    • 接口中可以有的内容
    • 接口默认方法的定义和使用
      • 默认方法定义格式
      • 默认方法的好处
    • 接口静态方法的定义和使用
      • 静态方法定义格式
      • 静态方法使用
    • 接口私有方法的定义和使用
      • 私有方法分类
      • 代码演示
  • Lambda表达式
    • 什么是Lambda
    • 函数式思想
    • 函数式接口
    • 体验Lambda
    • Lambda标准格式
    • Lambda表达式练习
      • Lambda表达式使用前提
      • 抽象方法是无参无返回值
      • 抽象方法是有参无返回值
      • 抽象方法是有参有返回值
      • Lambda表达式的省略模式
      • Lambda表达式的注意事项
  • Stream流
  • 体验Stream流
  • Stream流的思想
  • 获取Stream流的三种方式
  • Stream流中间操作方法
    • filter方法
    • limit&skip
    • concat&distinct
    • sorted
    • map&mapToInt
  • Stream流终结操作方法
    • 概念
    • 相关方法
    • 代码演示
  • Stream流综合练习
    • 案例需求
    • Actor类
    • 案例代码
  • Stream流的收集操作
    • 概念
    • 常用方法
    • 代码演示
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档