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

不可变集合

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

为什么要不可变合集

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

 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 自定义对象抛出!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值