IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Stream流、方法引用 -> 正文阅读

[Java知识库]Stream流、方法引用

Stream流

说到Stream便容易想到I/O Stream,而实际上,谁规定“流”就一定是“IO流”呢?在Java 8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊端。
使用流的步骤:
获取一个数据源(source)–>数据转换–>执行操作想要的结果,每次转换原有Stream对象不改变,返回一个新的Stream对象(可以多次转换),这就允许对其操作可以像链条一样排列,变成一个管道

获取流

java.util.stream.Stream 是Java 8新加入的最常用的流接口。(这并不是一个函数式接口。)
获取一个流非常简单,有以下几种常用的方式:

  • 所有的Collection 集合都可以通过stream 默认方法获取流;
  • Stream 接口的静态方法of 可以获取数组对应的流。

根据Collection获取流

首先, java.util.Collection 接口中加入了default方法stream 用来获取流,所以其所有实现类均可获取流。

List<String> list = new ArrayList<>();
// ...
Stream<String> stream1 = list.stream();

根据Map获取流

java.util.Map 接口不是Collection 的子接口,且其K-V数据结构不符合流元素的单一特征,所以获取对应的流
需要分key、value或entry等情况:

Map<String, String> map = new HashMap<>();
// ...
Stream<String> keyStream = map.keySet().stream();
Stream<String> valueStream = map.values().stream();
Stream<Map.Entry<String, String>> entryStream = map.entrySet().stream();

根据数组获取流

如果使用的不是集合或映射而是数组,由于数组对象不可能添加默认方法,所以Stream 接口中提供了静态方法
of :

String[] array = { "张无忌", "张翠山", "张三丰", "张一元" };
Stream<String> stream = Stream.of(array);

备注: of 方法的参数其实是一个可变参数,所以支持数组。

常用方法

package DemoStream01;

import java.util.ArrayList;
import java.util.List;

public class Demo01ForEach {
    public static void main(String[] args) {
        List<String> list =new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");


        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        //传统集合遍历,对集合中的数据进行过滤
        List<String> list1=new ArrayList<>();
        for (String name:list){
            if (name.startsWith("张")){
                list1.add(name);
            }
        }
        List<String> list2=new ArrayList<>();
        for (String name1:list1){
            if (name1.length()==3){
                list2.add(name1);
            }
        }
        //Stream流的方式,对数据中集合进行过滤
        list.stream()
                .filter(s -> s.startsWith("张"))
                .filter(s -> s.length()==3)
                .forEach(System.out::println);
    }
}

方法应用

package DemoStream01;

import java.util.stream.Stream;

public class Demo02ForEach {
    public static void main(String[] args) {
        Stream<String> srtream =Stream.of("张无忌","张三丰","周芷若");
        srtream.forEach(name -> System.out.println(name));//forEach接收一个Consumer接口函数,会将每一个流元素交给该函数进行处理

        Stream<String> stream =Stream.of("张无忌","张三丰","赵敏");
        Stream<String> results = stream.filter(s -> s.startsWith("张"));//filter用于对Stream流中的数据进行过滤
        System.out.println(results.count());//count方法类似于Collection中的size一样,流提供count方法来数一数其中方法的个数

        /*Stream流属于管道流只能被消费(使用)一次,第一个Stream流调用完毕方法,
        数据流转换到下一个Stream上,而这时Stream流已经使用完毕,也已经关闭了,所以代码会报IllegalStateException:
        : stream has already been operated upon or closed*/

        Stream<String> original = Stream.of("10","111","123");
        Stream<Integer> result = original.map(s -> Integer.parseInt(s));//如果需要流中的元素映射到另一个流中,可以使用Map方法
        result.forEach(s -> System.out.println(s));

        Stream<String> original1= Stream.of("10","101","123");
        Stream<String> result1 = original1.limit(2);//limit方法可以对流进行截取,只取前n个,参数是一个long型,如果集合当前长度大于参数
        //进行截取,否则不进行操作
        System.out.println(result1.count());

        Stream<String> original2 =Stream.of("张无忌","张三丰","赵敏");
        Stream<String> result2 = original2.skip(2);//如果希望跳过前几个元素,参数是一个long型,如果当前长度大于参数
        //则跳过前n个,否则会得到一个长度为0的空流
        System.out.println(result2);


        Stream<String> streamA =Stream.of("张无忌","张三丰");
        Stream<String> streamB =Stream.of("周芷若","赵敏");
        Stream<String> result3 = Stream.concat(streamA,streamB);//如果有两个流,那么可以使用Stream接口的静态方法contact
        //这是一个静态方法与java.lang.string当中的concat方法是不同的
        result3.forEach(s -> System.out.println(result3));
    }
}

练习
传统做法:

package DemoStream01;

import java.util.ArrayList;

public class Demo01Excercise {
    public static void main(String[] args) {
        //1、第一支队伍
        ArrayList<String> one=new ArrayList<>();
        one.add("迪丽热巴");
        one.add("杨幂");
        one.add("陈数");
        one.add("赵丽颖");
        one.add("宋轶");
        one.add("杨颖");
        one.add("杨千嬅");
        one.add("容祖儿");
        one.add("宋祖儿");

        //2、第一支队伍只要名字为3个字的成员姓名,存储到一个新的集合中
        ArrayList<String>one1= new ArrayList<>();
        for (String name:one){
            if (name.length()==3){
                one1.add(name);
            }
        }

        //3、第二支队伍
        ArrayList<String> two=new ArrayList<>();
        two.add("刘德华");
        two.add("刘备");
        two.add("刘谦");
        two.add("刘德华");
        two.add("张学友");
        two.add("黎明");
        two.add("成龙");
        two.add("甄子丹");
        two.add("李小龙");
        //4、第二支队伍只要姓刘的成员姓名,存储到一个新的集合中
        ArrayList<String> two1=new ArrayList<>();
        for (String name:two){
            if (name.startsWith("刘")){
                two1.add(name);
            }
        }
        //5、第二支队伍筛选后不要前两人
        ArrayList<String>two2= new ArrayList<>();
        for (int i = 2; i <two1.size() ; i++) {
            two2.add(two1.get(i));
        }
        //6、将两个队伍合并为1个队伍,存储到一个新的集合中
        ArrayList<String> all=new ArrayList<>();
        all.addAll(one1);
        all.addAll(two2);
        //7、根据姓名创建Person对象,存储到一个新集合中
        ArrayList<Person> persons =new ArrayList<>();
        for (String person:all){
            DemoStream01.Person personObject = new DemoStream01.Person(person);
            persons.add(personObject);
        }
        //7、打印整个队伍的Person对象信息
        for (DemoStream01.Person person :persons){
            System.out.println(person.getName());
        }


    }
}

使用Stream流

package DemoStream01;

import java.util.ArrayList;
import java.util.stream.Stream;

public class Demo02Excercise {
    public static void main(String[] args) {
        //第一支队伍
        ArrayList<String> one=new ArrayList<>();
        one.add("迪丽热巴");
        one.add("杨幂");
        one.add("陈数");
        one.add("赵丽颖");
        one.add("宋轶");
        one.add("杨颖");
        one.add("杨千嬅");
        one.add("容祖儿");
        one.add("宋祖儿");
        //1、第一支队伍只要名字为3个字的成员姓名,存储到一个新的集合中
        //第一支队伍筛选之后只要前三个人,存储到一个新集合中
        Stream<String> oneStream=one.stream().filter(name->name.length()==3).limit(3);

        //第二支队伍
        ArrayList<String> two=new ArrayList<>();
        two.add("刘德华");
        two.add("刘备");
        two.add("刘谦");
        two.add("刘德华");
        two.add("张学友");
        two.add("黎明");
        two.add("成龙");
        two.add("甄子丹");
        two.add("李小龙");
        //3、第二支队伍只要姓刘的成员姓名,存储到新的集合中
        //4、第二支队伍筛选之后不要前两个人,存储到新集合中
        Stream<String> twoStream= two.stream().filter(name->name.startsWith("张")).skip(2);

        //5、将两个队伍合并为1个队伍,存储到一个新的集合中
        //6、根据姓名创建Person对象,存储到一个新集合中
        //7、打印整个队伍的Person对象信息
       Stream.concat(oneStream,twoStream).map(name->new Person(name)).forEach(person -> System.out.println(person));

    }
}

方法引用

package StreamMethodUseDemo;
/*Lambda表达式的目的,打印参数传递的字符串
把参数s传递给了system.out,调用out对象中的方法printIn对字符串进行了输出
注意:
1、System.out对象是已经存在的
2、printIn方法是已经存在的
所以可以使用方法引用优化Lambda表达式
可以使用System.out方法直接引用(调用)printIn方法
*/

import LambdaTest.Calculate;

public class Demo01Printable {
    //定义一个方法,参数传递Printable接口,对字符串进行打印
    public static void printString(Printable p){
        p.print("Hello World");
    }

    public static void method(int num, Calcable lambda){
        System.out.println(lambda.calc(num));
    }

    public static void main(String[] args) {
        //调用printString方法,方法的参数Printable是一个函数式接口,所以可以传递Lambda
        printString(s-> System.out.println(s));
        printString(System.out::println);

        //1、通过对象名引用成员方法
        MethodRefObject obj = new MethodRefObject();
        printString(obj::printUppercase);

        //2、通过类名称引用静态方法
        method(10,Math::abs);
    }
}

package StreamMethodUseDemo;

public class Man extends Human{
    @Override
    public void sayHello() {
        System.out.println("大家好,我是Man");
    }
    //定义方法Method,参数传递Greetable接口
    public void Method(Greetable g){
        g.greet();
    }
    public void show1(){
        Method(()->new Human().sayHello());
        //使用super关键字代替父类对象
        Method(()->super.sayHello());
    }
    //3、使用方法引用来调用父类中的sayHello方法
    public void show2(){
        Method(super::sayHello);
    }

}

package StreamMethodUseDemo;

public class Husband {
    private void marry(Richable lambada){
        lambada.buy();

    }
    private void buyHouse(){
        System.out.println("买套房子");

    }
    public void beHappy(){
        marry(()-> System.out.println("买套房子"));
        //在lambda表达式中使用this关键字
        marry(()->this.buyHouse());
        //4、方法引用
        marry(this::buyHouse);
    }
}

package StreamMethodUseDemo;
//类构造器引用
public class Demo02Lambda {
    public static void printName(String name,PersonBuilder builder){
        System.out.println(builder.builderPerson(name).getName());
    }

    public static void main(String[] args) {
        printName("赵丽颖",name -> new Person(name));
        //5、类构造器引用
        printName("赵丽颖",Person::new);
    }
}

package StreamMethodUseDemo;

public class Demo02ArrayInitRef {
    private static int[] intArray(int length,ArrayBuilder builder){
        return builder.builderArray(length);
    }

    public static void main(String[] args) {
        int[] array=intArray(10,length -> new int[length]);
        //6、数组的构造器引用
        int[] array1=intArray(10,int[]::new);
        System.out.println(array.length);
    }
}

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-07 11:51:51  更:2021-08-07 11:53:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/10 20:12:42-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码