不可变集合 Stream流体系 异常概述,分类,和认识,异常的处理机制,异常的强大演示,自定义异常

本文介绍了Java中的不可变集合,强调了其在防御性编程和安全性方面的价值。通过示例展示了如何使用List、Set、Map的of方法创建不可变集合。接着,详细探讨了Stream流的特性,包括它的创建、中间操作和终结操作,并通过实例演示了如何使用Stream简化集合操作。此外,文章还讨论了Java异常处理的重要性,区分了编译时异常和运行时异常,并给出了异常处理的常见方式。最后,提到了自定义异常的创建及其在业务问题处理中的价值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

不可变集合

集合的数据项在创建的时候提供,并且在整个生命周期中都不可改变。否则报错

为什么要不可变合集

如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是个很好的实践。 或者当集合对象被不可信的库调用时,不可变形式是安全的

 List<Double> lists = List.of(666.3,555.2,777.2);

 Set<String> names = Set.of("我", "是", "笨", "蛋" );

Map<String, Integer> maps = Map.of("豹女",3, "索子哥", 5 , "迭嘉", 8);

定义完成后不可以修改,或者添加、删除

List、Set、Map接口中,都存在of方法可以创建不可变集合

Stream流

Stream初体验

目的是写一个String name 的名字的集合 把其中的名字是三个字的和姓张的给筛选出来
public class test {
    public static void main(String[] args) {
        List<String> name=new ArrayList<>();
        Collections.addAll(name,"张三","张无忌","张三丰","李四");//原始方法
//        List<String>zhang=new ArrayList<>();
//        for (String names : name) {
//            if(names.startsWith("张")){
//                zhang.add(names);
//            }
//        }
//        System.out.println(zhang);
//        List<String> zhangsan=new ArrayList<>();
//        for (String namess : zhang) {
//            if(namess.length()==3){
//                zhangsan.add(namess);
//            }
//        }
//        System.out.println(zhangsan);
        name.stream().filter(s->s.startsWith("张")&& s.length()==3).forEach(s-> System.out.println(s));//Stream 的方法
    }
}

Stream流核心思想

先得到集合或者数组的Stream流, 把元素放上去 然后就用这个Stream流简化的API来方便的操作元素

Stream 的作用

简化集合、数组操作的API。结合了Lambda表达式

Stream流的三类方法

获取Stream流 创建一条流水线,并把数据放到流水线上准备进行操作

中间方法 流水线上的操作。一次操作完毕之后,还可以继续进行其他操作。

终结方法 一个Stream流只能有一个终结方法,是流水线上的最后一个操作

获取stream流

Collection<String> list = new ArrayList<>();
        Stream<String> s =  list.stream();
        //Collection集合获取流
 Map<String, Integer> maps = new HashMap<>();// 键流
        Stream<String> keyStream = maps.keySet().stream(); // 值流
        Stream<Integer> valueStream = maps.values().stream();// 键值对流(拿整体)
        Stream<Map.Entry<String,Integer>> keyAndValueStream =  maps.entrySet().stream();
//      Map获取Stream流
//数组获取Stream流

   String[] names = {"张三","张无忌","张三丰","李四"};
        Stream<String> nameStream = Arrays.stream(names);
        Stream<String> nameStream2 = Stream.of(names);

总结 

集合通过Stream()方法调用

Stream的常用Api

forEach : 逐一处理(遍历)
count:统计个数
   -- long count();
filter : 过滤元素
   -- Stream<T> filter(Predicate<? super T> predicate)
limit : 取前几个元素
skip : 跳过前几个
map : 加工方法
concat : 合并流
public class teat3 {


    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        Collections.addAll(list,"王牛马","张牛马","牛爷爷","牛图图","牛马");
        //过滤元素 filter 和 遍历 forEach
        list.stream().filter(s -> s.startsWith("张")).forEach(s -> System.out.println(s));//这是过滤的姓张的
        System.out.println("_____________________________");
        long size =list.stream().count();//计算个数 4
        long sizes=list.stream().filter(s -> s.length()==3).count(); //只要长度为3的 有4个
        System.out.println(size);
        System.out.println(sizes);
        //取前2个元素
        list.stream().limit(2).forEach(s -> System.out.println(s));
        System.out.println("_____________________________");
        //跳过前3个元素
        list.stream().skip(3).forEach(s -> System.out.println(s));
        System.out.println("_____________________________");
        //map加工方法
        //原理 第一个参数原材料  -> 第二个参数是加工后的结果
        list.stream().map(s -> "我是"+s).forEach(s -> System.out.println(s));
        System.out.println("_____________________________");
        //合并流
        Stream<String> s1= list.stream().filter(s -> s.startsWith("牛"));
        Stream<String> s2= Stream.of("nb","nb");
        Stream<String> s3=Stream.concat(s1,s2);
        //s3.forEach(s -> System.out.println(s));
        System.out.println("_____________________________");
        //去重复元素
        s3.distinct().forEach(s -> System.out.println(s));

结果
张牛马
_____________________________
5
4
王牛马
张牛马
_____________________________
牛图图
牛马
_____________________________
我是王牛马
我是张牛马
我是牛爷爷
我是牛图图
我是牛马
_____________________________
_____________________________
牛爷爷
牛图图
牛马
nb

Stream 流的收集操作

public class test5 {
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        Collections.addAll(list,"王牛马","张牛马","牛爷爷","牛图图","牛马","牛皮","牛皮");
        //把元素收集到List集合中
        Stream<String> s1= list.stream().filter(s -> s.startsWith("牛"));
        List<String> niu=  s1.collect(Collectors.toList());
        System.out.println(niu);
        //流只能使用一次 用完s1就没了,重新定义set的s2
        //把元素收集到Set集合中
        Stream<String> s2=list.stream().filter(s ->s.startsWith("牛"));
        Set<String> niuSet=s2.collect(Collectors.toSet());
        System.out.println(niuSet);
        //把元素收集到数组中
        Stream<String> s3=list.stream();
        Object []arr=s3.toArray();
        //System.out.println(arr);
        //要是有其他类型的
//        String[] arrs = s3.toArray(String[]::new);
        System.out.println("Arrays数组内容:" + Arrays.toString(arr));
    }
}
结果
[牛爷爷, 牛图图, 牛马, 牛皮, 牛皮]
[牛爷爷, 牛图图, 牛皮, 牛马]
Arrays数组内容:[王牛马, 张牛马, 牛爷爷, 牛图图, 牛马, 牛皮, 牛皮]

什么是异常

异常是程序在“编译”或者“执行”的过程中可能出现的错误,注意:语法错误不算在异常体系中。 比如:数组索引越界、空指针异常、 日期格式化异常,等…

为什么要学习异常

异常一旦出现了,如果没有提前处理,程序就会退出JVM虚拟机而终止. 研究异常并且避免异常,然后提前处理异常,体现的是程序的安全, 健壮性 

异常分为 

编译时异常,是在编译成class文件时必须要处理的异常,也称之为受检异常

运行时异常,在编译成class文件不需要处理,在运行字节码文件时可能出现的异常

常见的异常

数组索引越界异常: ArrayIndexOutOfBoundsException。*/
int[] arr = {1, 2, 3}
System.out.println(arr[3]); // 运行出错,程序终止
空指针异常 : NullPointerException。直接输出没有问题。但是调用空指针的变量的功能就会报错
 String name = null;
System.out.println(name.length());
类型转换异常:ClassCastException
Object o = 23;
String s = (String) o;  // 运行出错,程序终止
数学操作异常:ArithmeticException
int c = 10 / 0;
数字转换异常: NumberFormatException
String number = "23aabbc";//
        //Integer it = Integer.valueOf(number); // 运行出错,程序终止
        //System.out.println(it + 1);

     编译时异常

编译时异常:继承自Exception的异常或者其子类 编译阶段报错,必须处理,否则代码不通过。

异常处理方式

方式1 

throws:用在方法上,可以将方法内部出现的异常抛出去给本方法的调用者处理

抛出异常格式

方法 throws 异常1 ,异常2 ,异常3 ..{ }

规范做法

throws Exception{ }

方式2

监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理。 这种方式还可以,发生异常的方法自己独立完成异常的处理,程序可以继续往下执行。

格式:

try{        // 监视可能出现异常的代码!    }catch(异常类型1 变量){        // 处理异常    }catch(异常类型2 变量){        // 处理异常    }...

ctrl+ALT+T 快捷键

方式3

前两者集合

方法直接将异通过throws抛出去给调用者 调用者收到异常后直接捕获处理。

总结

底层的异常抛出去给最外层,最外层集中捕获处理。

自定义异常

Java无法为这个世界上全部的问题提供异常类

如果需要管理业务问题就西药自己定义异常类

好处是

可以提醒自己业务问题

如果出现bug,可以很清晰的指出出出错的地方

自定义编译时异常        定义一个异常类继承Exception.  重写构造器。  在出现异常的地方用throw new 自定义对象抛出,

自定义运行时异常 定义一个异常类继承RuntimeException. 重写构造器。 在出现异常的地方用throw new 自定义对象抛出!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值