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知识库 -> java30-Stream流-生成方式-中间操作方式(filter-limit-skip-concat-distinct-sorted-map-mapToInt)-终结操作-收集操作 -> 正文阅读

[Java知识库]java30-Stream流-生成方式-中间操作方式(filter-limit-skip-concat-distinct-sorted-map-mapToInt)-终结操作-收集操作

Stream流

初识Stream流

Stream流把真正的函数式编程风格引入到java中
案例:需求:
创建集合,存储多个字符串元素;把集合中“张”开头的字符串存储到另外的集合中;把“张”开头的集合中的长度大于3的元素存储到另外集合中;遍历上一步得到的集合。

public class StreamDemo {
    public static void main(String[] args) {
       

        ArrayList<String> array = new ArrayList<String>();

        array.add("林俊杰");
        array.add("张信哲");
        array.add("王一博");
        array.add("许嵩");
        array.add("张杰");
        array.add("张艺兴");

        ArrayList<String> zhang = new ArrayList<String>();
        for(String s:array){
            if(s.startsWith("张")){
                zhang.add(s);
            }
        }
        System.out.println( "zhang集合:"+zhang);

        ArrayList<String> zhang3 = new ArrayList<String>();
        for(String s :zhang){
            if(s.length() == 3){
                zhang3.add(s);
            }
        }
        System.out.println("zhang3集合:" + zhang3);
        System.out.println("-----------");

        // 使用stream流实现
        array.stream().filter(s->s.startsWith("张")).filter(s-> s.length() == 3).forEach(s-> System.out.println(s));
        * 注意:
        * 意思:array.stream生成流、过滤张、过滤长度为3、forEach逐一打印
        // 使用引用类方法简化
        System.out.println("简化");
        array.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==3).forEach(System.out::println);
    }
}

Stream流的生成方式

Stream的使用:

1 生成流
	通过数据源(集合、数组等)生成流
	list.stream()
2 中间操作
	一个流后面可以跟随零个或多个中间操作,其目的主要是打开流,做出某种程度的数据过滤/映射,然后返回一个新的流,交给下一个操作使用。
	filter()
3 终结操作
	一个流只能有一个终结操作,当这个操作执行后,流就被使用“光”了,无法再被操作。
	forEach()

Stream流的常见生成方式:

1 Collection体系的集合可以使用默认方法stream()生成流
	default Stream< E > stream()
2 Map 体系的集合间接的生成流
	可以使用方法keySet方法、values方法、entrySet方法
3 数组可以通过Stream接口的静态方法of(T...values)生成流
	其中静态方法of(T....values)是可变参数。
	* Stream.of(T...values)

代码:

public class StreamDemo1 {
    public static void main(String[] args) {
        // Collection体系的集合可以使用默认方法stream()生成流
        // List 和 Set 是Collection的儿子
        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> keyStrem = map.keySet().stream();
        // map.ksySet得到是 键的集合,集合通过stream方法可以得到stream流
        Stream<Integer> valueStream = map.values().stream();
        // map.values 得到 值的集合,集合通过stream方法可以得到stream流
        Stream<Map.Entry<String, Integer>> kvStream = map.entrySet().stream();
        // map.entrySet 得到键值对 对象的集合

        // 数组可以通过Stream接口的静态方法of(T...values)生成流
        String[] strArray = {"you","are","my","pretty","sunshine"};
        Stream<String> strArray1 = Stream.of(strArray);
        Stream<String> strStream2 = Stream.of("hello", "world");
        Stream<Integer> integerStream = Stream.of(10, 20, 30);
    }
}

Stream流的中间操作方式

中间操作方法:

方法名说明
Stream < T > filter(Predicate predicate)用于对流中的数据进行过滤
Predicate接口中的方法,boolean test(T t):对给定的参数进行操作,返回一个布尔值
Stream< T > limit(long maxSize)返回此流中的元素组成的流,截取前指定参数个数的数据
Stream< T > skip(long n)跳过指定参数个数的数据,返回由该流的剩余元素组成的流
static < T > Stream < T > concat(Stream a,Stream b)合并a和b两个流为一个流
Stream< T > distinct()返回由该流的不同元素(Object.equals(Object))组成的流
Stream< T > sorted()返回由此流的元素组成的流,根据自然顺序排序
Stream< T > sorted(Comparator comparator返回由该留的元素组成的流,根据提供的Comparator进行排序
Comparator接口中的方法 int compare(T o1,T o2)
< R > Stream < R > map(Function mapper)返回由给定函数应用于此流的元素的结果组成的流
Function接口中的方法 R apply(T t)
IntStream mapToInt(ToIntFunction mapper)返回一个IntStream,其中包含将给定函数应用于此流的元素的结果
IntStream 表示原始int流ToIntFunction接口中的方法 int applyAsInt(T value)
其中IntStream接口中有方法int sum() 返回此流中元素的总和

案例1:filter

public class StreamDemo2 {
    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集合中的以张开头的元素在控制台输出
        // 流生成方式1 Collection集合中静态方法Stream方法
        list.stream().filter((String s) -> s.startsWith("张")).forEach((String s)-> System.out.println(s));
        // 省略 引用类的方法 对象::实例方法
        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);
    }
}

案例2:limit skip

public class StreamDemo3 {
    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.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);
        // 输出结果:王一博 胡夏
    }
}

案例3:dictinct concat

public class StreamDemo4 {
    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);
        // 需求2:跳过2个数据组成一个流
        Stream<String> s2 = list.stream().skip(2);
        // 需求3:合并需求1和需求2得到的流,并把结果在控制台输出
//        Stream.concat(s1, s2).forEach(System.out::println);
        // 需求4:合并需求1和需求2得到的流,并把结果在控制台输出,要求字符串元素不能重复
        // 输出:林俊杰 张信哲 王一博 胡夏 王一博 胡夏 张杰 张艺兴
        System.out.println("---------");
        Stream.concat(s1, s2).distinct().forEach(System.out::println);
        // 输出结果:林俊杰 张信哲 王一博 胡夏 张杰 张艺兴
        // 同时执行两个Stream.concat 会报错。IllegalStateException: stream has already been operated upon or closed
        // 流只能运行(调用中间或终端流操作)一次。
    }
}

案例4:sorted

public class StreamDemo5 {
    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("zhagnwuji");

        // 需求1:按照字母顺序把数据在控制台输出
//        list.stream().sorted().forEach(System.out::println);
        // 需求2:按照字符串长度把数据在控制台输出
        // 匿名内部类
//        list.stream().sorted(new Comparator<String>() {
//            @Override
//            public int compare(String s1, String s2) {
//                return s1.length() - s2.length();
//            }
//        }).forEach(System.out::println);
        // 输出结果有问题:liuyan
        //zhangmin
        //zhagnwuji
        //linqingxia
        //zhangmanyu
        //wangzuxian
        //其中 后三个没有按照字母顺序排 而是按照添加顺序
        // Lambda表达式
//        list.stream().sorted((s1,s2)->s1.length()-s2.length()).forEach(System.out::println);
        // 长度相同 按照自然顺序排
        list.stream().sorted((s1,s2)->{
            int sum = s1.length()-s2.length();
            int sum2 = sum == 0?s1.compareTo(s2):sum;
            return sum2;
        }).forEach(System.out::println);
        // 输出结果:
        /*liuyan
        zhangmin
        zhagnwuji
        linqingxia
        wangzuxian
        zhangmanyu*/
    }
}

案例5:map mapToInt

public class StreamDemo6 {
    public static void main(String[] args) {
         ArrayList<String> array = new ArrayList<String>();

         array.add("10");
         array.add("20");
         array.add("30");
         array.add("40");
         array.add("50");
         // 需求:将集合中的字符串数据转化为整数之后在控制台输出
//        array.stream().map(s -> Integer.parseInt(s)).forEach(System.out::println);
//        array.stream().map(Integer::parseInt).forEach(System.out::println);
        // 方法引用 分别是 类的方法(类名::静态方法)、对象的实例方法(对象的成员方法)

//        array.stream().mapToInt(Integer::parseInt).forEach(System.out::println);
        // mapToInt方法的返回值类型是 IntStream 其中有个int sum()方法 返回此流中元素的总和。
        int result = array.stream().mapToInt(Integer::parseInt).sum();
        System.out.println(result);
        // 输出结果150

    }
}

Stream流的常见终结操作方法

方法名说明
viod forEach(Consumer action)对此流的每个元素执行操作
Consumer接口中的方法 void accept(T t)对给定的参数执行此操作
long count()返回此流中的元素个数

案例:

public class StreamDemo7 {
    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.stream().forEach(System.out::println);
        // 需求2:统计集合中有几个以张开头的元素,并把统计结果在控制台输出
        long result = list.stream().filter(s -> s.startsWith("张")).count();
        System.out.println(result);
        // 输出结果是3
    }
}

Stream流练习

需求:
有两个ArrayList集合,分别存储6名男演员和6名女演员名称,完成如下操作:
1 男演员只要名字为三个字的前三个人
2 女演员只要姓林的,并且不要第一个人
3 把过滤后的男演员名字和女演员名字合并在一起
4 把上一个步操作后的元素作为构造方法的参数创建演员对象,遍历数据
演员类Actor,有一个成员变量,一个带参构造方法,以为其对应的get/set方法

public class StreamDemo {
    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("王祖贤");

        // 1 男演员只要名字为三个字的前三个人
        Stream<String> manStream = manList.stream().filter(s->s.length() ==3).limit(3);
        // 2 女演员只要姓林的,并且不要第一个人
        Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);
        // 3 把过滤后的男演员名字和女演员名字合并在一起
        Stream<String> conStream = Stream.concat(manStream, womanStream);
        // 4 把上一个步操作后的元素作为构造方法的参数创建演员对象,遍历数据
//        conStream.map(Actor::new).forEach(System.out::println);
        // 引用方法是 引用构造器 = 类::构造方法
        conStream.map(Actor::new).forEach(p-> System.out.println(p.getName()));
    }
}

Stream流的收集操作

  • 对数据使用Stream流的方式后,把流中的数据收集到集合中,收集方法是:R collect(Collector collector)
  • 参数Collector 是一个接口interface,interface Collector< T,A,R >
  • 工具类Collectors类实现了各种有用的还原操作的Collector
  • Collector类提供了具体的收集方法:
方法名说明
public static < T > Collector toList()把元素收集到List集合中
public static < T > Collector toSet()把元素收集到Set集合中
public static < T > Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中

案例:

public class test7 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();

        list.add("林俊杰");
        list.add("张信哲");
        list.add("王一博");
        list.add("刘维");

//        // 需求1:得到名字为三个字的流
//        Stream<String> stringList = list.stream().filter(s -> s.length() == 3);
//        // 需求2:把使用Stream流操作完毕的数据收集到List集合中
//        List<String> names = stringList.collect(Collectors.toList());
//        for(String name:names ){
//            System.out.println(name);
//        }

        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> integerStream = set.stream().filter(a -> a > 25);
//        // 需求4:把使用Stream流操作完毕的数据收集到Set集合中
//        Set<Integer> ages = integerStream.collect(Collectors.toSet());
//        for(Integer age : ages){
//            System.out.println(age);
//        }

        String[] strArray = {"林俊杰,30","张信哲,35","王一博,33","刘维,25"};
        // 需求5:字符串中年龄大于28的流
        Stream<String> ageStream = Stream.of(strArray).filter(s ->
            Integer.parseInt(s.split(",")[1]) >28 );
        // 需求6:把使用Stream流操作完毕的数据收集到Map集合中,并遍历
        Map<String,Integer> map = ageStream.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("姓名:" + value + ", " + "年龄:" + key);
        }
    }
}
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-15 22:18:55  更:2022-03-15 22:22:02 
 
开发: 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年11日历 -2024/11/24 10:00:02-

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