学Java第四十五天——不可变集合、Stream流

一、不可变集合

含义

应用场景

格式:

List.of()参数是个可变参数,可以放可变个数的参数。

一旦创建,不能删除、添加,不能修改。

Set:

Map的不可变集合,of(),键值对数量不能超过10,代码如下:

创建Map的不可变集合,长度超过10个键值对,方法是将键值对打包成Map.Entry的类型,传递超过10个元素的数组就行了

最后会报错,不能添加

简化代码:

最后会报错,因为不可变集合不能添加元素。

最后用copyof(hashmap类型的对象)即可,因为copyof底层原理就是上面那一行 的简化代码。

心得:可变参数是一个数组,所以实参传递一个数组就可以了。

键值对类型是 Map.Entry

创建一个键值对类型的数组:Map.Entry [] arr=new Map.Entry[0];//长度为0

把一个集合类型转变为数组类型:集合名.toArray(参数为某个类型的数组对象)

自己写代码:

java 复制代码
package com.不可变集合;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class 不可变集合 {
    public static void main(String[] args) {
        List<Integer> list=List.of(1,2,7,8,9);
        //list是个不可变集合
        //list.add(2);//会报错

        Set<String> set=Set.of("aaa","bbb","ccc");
        //set.remove("bbb");//set是一个不可变集合,会报错

        Map<String,String> map=Map.of("aaa","123","bbb","222");
        //map.put("bbb","456");

        HashMap<String,Integer> hm=new HashMap<>();
        hm.put("aaa",111);
        hm.put("bbb",222);
        hm.put("ccc",333);
        
        Map<String,Integer> map1=Map.copyOf(hm);
        //map1是个不可变集合,所以......
        map1.remove("aaa");

    }
}

总结

二、stream流

2.1如何变成stream流



1、单列集合

java 复制代码
package com.Stream;

import java.util.ArrayList;
import java.util.Collections;

public class Streamdemo1 {
    public static void main(String[] args) {
        //单列集合,用collection接口自带的stream方法获取流水线,
        // 并把集合中的数据放到流水线上
        ArrayList<Integer> list=new ArrayList<>();
        Collections.addAll(list,1,2,3,5,7,90);

        list.stream().forEach(s-> System.out.println(s));
    }
}

在list/set上直接调用stream方法

2、双列集合

要先把map调用keyset和entryset方法变成set集合,之后才能用collection接口的stream方法

entryset()方法得到的集合数据类型是Map.entry类型,打印的结果是:

java 复制代码
[aaa=1, ccc=3, bbb=2, ddd=4]
java 复制代码
package com.Stream;

import java.util.HashMap;

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

        HashMap<String,Integer> map=new HashMap<>();

        map.put("aaa",1);
        map.put("bbb",2);
        map.put("ccc",3);
        map.put("ddd",4);

        map.entrySet().stream().forEach(s-> System.out.println(s));
        map.keySet().stream().forEach(s-> System.out.println(s));
        
    }
}

3、数组array

用arrays.stream()方法

java 复制代码
package com.Stream;

import java.util.Arrays;

public class Streamdemo3 {
    public static void main(String[] args) {
        //对数组stream
        int[] arr={1,2,6,8,9};

        Arrays.stream(arr).forEach(s-> System.out.println(s));
    }
}

4、零散数据

用stream接口的of()方法

java 复制代码
package com.Stream;

import java.util.stream.Stream;

public class Streamdemo4 {
    public static void main(String[] args) {
        Stream.of(1,2,3,4).forEach(s-> System.out.println(s));

        int []arr={1,2,3};
        Stream.of(arr).forEach(s-> System.out.println(s));//[I@682a0b20
        
        String []arr2={"aaa","dd","c"};
        Stream.of(arr2).forEach(s-> System.out.println(s));//aaa
        //dd//c


    }
}

用stream接口的of方法时,参数是可变参数,可以传递零散数据,也可以传递数组,但是数组必须得是引用类型,不能是基本数据类型。

2.2stream流的中间方法

**将字符串变成int类型:**Integer.parseInt()方法,参数填写字符串,返回值是int类型。

1、filter()过滤

filter参数里面的匿名内部类return后面是boolean类型,只留下符合的元素,true留下,false过滤掉

注意1:代码示例:

java 复制代码
ArrayList<String> list=new ArrayList<>();
        Collections.addAll(list,"张无极","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");

        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {

                return s.startsWith("张");
            }
        }).forEach(s-> System.out.println(s));


        System.out.println("=====================");

        list.stream().filter(s->s.startsWith("张")).forEach(s-> System.out.println(s));

        System.out.println("=========================");
        list.stream()
                .filter(s->s.startsWith("张"))
                .filter(s->s.length()==3)
                .forEach(s-> System.out.println(s));

2、limit()获取前几个元素

java 复制代码
list.stream()  //获取前三个元素
                .limit(3)
                .forEach(s-> System.out.println(s));

3、skip()跳过前几个元素

java 复制代码
list.stream()//"张基尼","赵敏","王朔"
                .skip(2)
                .limit(3)
                .forEach(s-> System.out.println(s));

4、distinct()元素去重,依赖hashCode和equals方法

自己定义的引用数据类型一定要重写hashcode和equals方法

java 复制代码
ArrayList<String> list2=new ArrayList<>();
        Collections.addAll(list2,"张无极","张无极","张无极","张无极","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");
        System.out.println("+++++++++++++++");
        list2.stream().forEach(s-> System.out.println(s));

        System.out.println("========================");
        list2.stream()//去重
                .distinct()
                .forEach(s-> System.out.println(s));

输出:

java 复制代码
+++++++++++++++
张无极
张无极
张无极
张无极
周芷若
张基尼
赵敏
王朔
张忙
李帅
谢想
========================
张无极
周芷若
张基尼
赵敏
王朔
张忙
李帅
谢想

5、concat()合并a流和b流为一个流,新流为ab的父类类型

java 复制代码
ArrayList<String> list3=new ArrayList<>();
        Collections.addAll(list3,"张无极","臭蛋","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");

        ArrayList<String> list4=new ArrayList<>();
        Collections.addAll(list4,"张无极","张有极","张很极","张少极","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");

        System.out.println("----------------------------");
        Stream.concat(list3.stream(),list4.stream()).forEach(s-> System.out.println(s));

输出

java 复制代码
----------------------------
张无极
臭蛋
周芷若
张基尼
赵敏
王朔
张忙
李帅
谢想
张无极
张有极
张很极
张少极
周芷若
张基尼
赵敏
王朔
张忙
李帅
谢想

6、map()转换流中的数据类型

string字符串类型把每个元素中的数字,抽取出来,再转换成整数类型。

java 复制代码
System.out.println("---------------------");
        ArrayList<String> list5=new ArrayList<>();
        Collections.addAll(list5,"张无极-15","臭蛋-16","周芷若-25","张基尼-100","赵敏-52","王朔-29","张忙-57","李帅-22","谢想-56");

        list5.stream().map(new Function<String, Integer>() {
            @Override
            public Integer apply(String s) {
                String []arr=s.split("-");//得到的是一个数组
                String age=arr[1];
                int i = Integer.parseInt(age);
                return i;
            }
        }).forEach(s-> System.out.println(s));


        //简化
        list5.stream()
                .map(s->Integer.parseInt(s.split("-")[1]))
                .forEach(s-> System.out.println(s));

输出

java 复制代码
---------------------
15
16
25
100
52
29
57
22
56
15
16
25
100
52
29
57
22
56

2.3stream流的终结方法

1、forEach()

foreach返回值是void,而不是stream类型,所以是终结方法。

2、count()

返回值是long,整数类型,是返回流中的元素个数。

3、toArray()方法

把处理后的stream流存储到数组中保存起来,以便后续使用

有两种,一种无参,一种有参

java 复制代码
package com.Stream;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.function.IntFunction;

public class Last_method {
    public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        Collections.addAll(list,"张无极","周芷若","张基尼","赵敏","王朔","张忙","李帅","谢想");

        long count = list.stream().count();
        System.out.println(count);

        System.out.println("无参");
        //无参
        Object[] s = list.stream().toArray();//s是流中的元素组成的数组
        System.out.println(Arrays.toString(s));

        System.out.println("有参");
        //有参
        String[] array = list.stream().toArray(new IntFunction<String[]>() {
            @Override   //value是流中元素的个数
            public String[] apply(int value) {
                return new String[value];
            }
        });
        System.out.println(Arrays.toString(array));


    }
}

输出

java 复制代码
8
无参
[张无极, 周芷若, 张基尼, 赵敏, 王朔, 张忙, 李帅, 谢想]
有参
[张无极, 周芷若, 张基尼, 赵敏, 王朔, 张忙, 李帅, 谢想]

lambda表达式

java 复制代码
System.out.println(Arrays.toString(list.stream().toArray(value -> new String[value])));

4、collect()方法

有toList 、toSet 、toMap三个方法

java 复制代码
package com.Stream;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

public class Last_method_2 {
    public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        Collections.addAll(list,"张无忌-男-21","李晨-男-41","张良-男-28","丹淡-女-21","帅比-男-28");

        //筛选出男生并收集到list集合中
        List<String> collect = list.stream()
                .filter(s->"男".equals(s.split("-")[1]))
                .collect(Collectors.toList()); //toList方法是创建一个ArrayList集合
        System.out.println(collect);

        //筛选出男生并收集到set集合中
        Set<String> set = list.stream()
                .filter(s->"男".equals(s.split("-")[1]))
                .collect(Collectors.toSet());//toset方法是创建一个hashset集合会自动去重
        System.out.println(set);

        //筛选出男生并收集到map集合当中,键是名字,值是年龄
        Map<String, Integer> map = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toMap(new Function<String, String>() {
                    @Override
                    public String apply(String s) {

                        return s.split("-")[0];
                    }
                }, new Function<String, Integer>() {
                    @Override
                    public Integer apply(String s) {
                        return Integer.parseInt(s.split("-")[2]);
                    }
                }));
        System.out.println(map);//map集合千万不能用键重复的集合。会报错
    }
}

输出

java 复制代码
[张无忌-男-21, 李晨-男-41, 张良-男-28, 帅比-男-28]
[李晨-男-41, 张无忌-男-21, 张良-男-28, 帅比-男-28]
{张良=28, 帅比=28, 李晨=41, 张无忌=21}

lambda表达式

java 复制代码
Map<String, Integer> map2 = list.stream()
                .filter(s -> "男".equals(s.split("-")[1]))
                .collect(Collectors.toMap(s -> s.split("-")[0], s -> Integer.parseInt(s.split("-")[2])));
        System.out.println(map2);

2.4总结

2.5代码练习题

java 复制代码
package com.Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class test1 {
    public static void main(String[] args) {
        ArrayList<Integer> list=new ArrayList<>();
        Collections.addAll(list,1,2,3,4,5,6,7,8,9,10);

        List<Integer> collect = list.stream()
                .filter(s -> s % 2 == 0)
                .collect(Collectors.toList());
        System.out.println(collect);
    }
}
java 复制代码
package com.Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;

public class test2 {
    public static void main(String[] args) {
        ArrayList<String> list=new ArrayList<>();
        Collections.addAll(list,"zhangsan,23","lisi,24","wangwu,25");

        Map<String, Integer> map = list.stream()
                .filter(s -> Integer.parseInt(s.split(",")[1]) >= 24)
                .collect(Collectors.toMap(s -> s.split(",")[0], s -> Integer.parseInt(s.split(",")[1])));
        System.out.println(map);
    }
}
java 复制代码
package com.Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class test3 {
    public static void main(String[] args) {
        ArrayList<String> manList=new ArrayList<>();
        ArrayList<String> WomanList=new ArrayList<>();
        Collections.addAll(manList,"李晨,23","苏无名,25","陆凌枫,29","潇洒哥,24","刘晓雷,33","范凯,58");
        Collections.addAll(WomanList,"杨阳晨,23","杨新宇,25","杨晓岚,26","丹丹,24","欣欣,37","佳佳,18");

        Stream<String> stream1 = manList.stream()
                .filter(s -> s.split(",")[0].length() >= 3)
                .limit(2);

        Stream<String> stream2 = WomanList.stream()
                .filter(s -> s.startsWith("杨"))
                .skip(1);

        //类型转换用map方法,封装成actor类型
        /*List<actor> collect = Stream.concat(stream1, stream2).map(new Function<String, actor>() {
            @Override
            public actor apply(String s) {
                String name = s.split(",")[0];
                int age = Integer.parseInt(s.split(",")[1]);
                return new actor(name, age);
            }
        }).collect(Collectors.toList());*/

        //System.out.println(collect);

        List<actor> collect1 = Stream.concat(stream1, stream2).map(s -> new actor(s.split(",")[0], Integer.parseInt(s.split(",")[1])))
                .collect(Collectors.toList());
        System.out.println(collect1);


    }
}

两个流concat变成一个流,只能用一次,第二次contat就会报错。

相关推荐
q***48312 小时前
【springboot】Spring 官方抛弃了 Java 8!新idea如何创建java8项目
java·spring boot·spring
CodeCraft Studio2 小时前
Excel处理控件Aspose.Cells教程:使用Python从Excel工作表中删除数据透视表
开发语言·python·excel·aspose·aspose.cells·数据透视表
少睡点觉2 小时前
LeetCode 238. 除自身以外数组的乘积 问题分析+解析
java·算法·leetcode
952362 小时前
数据结构-二叉树
java·数据结构·学习
学IT的周星星2 小时前
SpringMVC请求参数的绑定
java·开发语言
普通网友2 小时前
高性能TCP服务器设计
开发语言·c++·算法
普通网友2 小时前
C++与硬件交互编程
开发语言·c++·算法
一 乐2 小时前
宠物猫店管理|宠物店管理|基于Java+vue的宠物猫店管理管理系统(源码+数据库+文档)
java·前端·数据库·vue.js·后端·宠物管理
r***99822 小时前
在2023idea中如何创建SpringBoot
java·spring boot·后端