0
点赞
收藏
分享

微信扫一扫

学习Java第16天

倪雅各 2022-03-30 阅读 27
java-ee

不可变集合

不可变集合,就是不可修改的集合

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

为什么要创建不可变集合?

如果某个数据不能被修改,把它防御性地拷贝到不可变集合中是个很好的实践

或者当集合对象被不可新的库调用时,不可变形式是安全的

package com.itheima.d6_map_test;
import java.util.*;
//使用Stream流
public class StreamTest {
    public static void main(String[] args) {
        //不可变集合list集合
        List<Double> lists=List.of(569.6,89.3,45.2,67.2);
        //lists.add(678.3);
        //lists.set(2,56.9);
        System.out.println(lists);
        double i=lists.get(1);
        System.out.println(i);
        //不可变的set集合
        Set<String> names= Set.of("迪丽热巴","马尔扎哈");
        System.out.println(names);
        Map<String,Integer> maps=Map.of("华为",1,"Java",2);
        //maps.put("是吗",3);
        System.out.println(maps);
    }
}

不可变集合的特点?

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

如何创建不可变集合?

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

Stream流:

在Java8中,得益于Lambda所带来的函数时编程,引入了一个全新的Stream流概念

目的:用于简化集合和数组操作的API

Stream流的思想:

1.先得到集合或者数组的Stream流

2.把元素放上去

3.然后就用这个Stream流去简化的API来方便的操作元素

package com.itheima.d7_stream;

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

//初步体验Stream流的方便与快捷
public class StreamTest {
    public static void main(String[] args) {
        List<String> names=new ArrayList<>();
        Collections.addAll(names,"张三丰","张无忌","周芷若","赵敏");
        // System.out.println(names);
        /*List<String> zhangList = new ArrayList<>();
        for (String name:names) {
            if(name.startsWith("张")){
                zhangList.add(name);
            }
        }
        System.out.println(zhangList);
        //找名称长度是三的数据
        List<String> zhangTree = new ArrayList<>();
        for(String name:zhangList){
            if(name.length()==3){
                zhangTree.add(name);
            }
        }
        System.out.println(zhangTree);
        //Stream流*/
        names.stream().filter(s
                -> s.startsWith("张")).filter(s -> s.length() == 3).
                forEach(s-> System.out.println(s));
    }
}

Stream流的作用是什么?结合了什么技术?

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

说说Stream流的思想和使用步骤

先得到集合或者数组的Stream流

把元素放上去

然后就用这个Stream流简化的API来方便的操作元素

Stream流的三种用法:

获取Stream流

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

中间方法

流水线上的操作,一次操作完毕后,还可以继续进行其他操作

终结方法:

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

{
    public static void main(String[] args) {
        /*----------Collection集合获取数据----------*/
        Collection<String> list = new ArrayList<>();
        Stream<String> s=list.stream();
        /*------------Map集合获取流-------------*/
        Map<String,Integer> map1=new HashMap<>();
        //键值
        Stream<String> keyStream=map1.keySet().stream();
        //值流
        Stream<Integer> valuesStream=map1.values().stream();
        //键值对象
        Stream<Map.Entry<String,Integer>> keyAndValueStream=map1.entrySet().stream();
        /*-----------数值获取数据----------*/
        String[] names={"赵敏","小姐","周芷若"};
        Stream<String> nameStream=Arrays.stream(names);
        Stream<String> name=Stream.of(names);
    }
}

集合获取Stream流的方式?

集合获取Stream的方式是通过调用stream()方法实现的

数组获取Stream流的方式?

 

 

package com.itheima.d7_stream;

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

public class StreamTest2 {
    /*Stream流的常用API
    * forEach:逐一处理
    * count:统计个数  long count()
    *limit:取前几个元素
    *skip跳过前几个
    * map:加工方法
    * concat:合并流
    * */
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.stream().filter(s-> s.startsWith("张")).
                forEach(s-> System.out.println(s));
        long size = list.stream().filter(s -> s.length() == 3).count();
        System.out.println(size);
        list.stream().filter(s->s.startsWith("张")).limit(2).forEach(System.out::println);
        list.stream().filter(s->s.startsWith("张")).skip(2).forEach(System.out::println);
        //map加工方法
        //给集合元素的前面加上一个黑马字样
        list.stream().map(s->"黑马的"+s).forEach(System.out::println);
        //需求把所有的名称加工成一个学生对象
        list.stream().map(s-> new Student(s)).forEach(s-> System.out.println(s));
        //合并流
        Stream<String> s1=list.stream().filter(s->s.startsWith("张"));
        Stream<String> s2=Stream.of("Java1","Java2");
        Stream<String> s3=Stream.concat(s1,s2);
        s3.forEach(s-> System.out.println(s));
    }
}

注意:中间方法也称为非终结方法,调用完成后返回新的Stream流可以继续使用,支持链式编程

在Stream流中无法修改集合,数组中的数据

注意:终结操作方法,调用完后流就无法继续使用了,原因是不会返回Stream了

总结:终结和非终结方法的含义是什么?

终结方法后流不可以继续使用,非终结方法会返回新的流,支持链式编程

Stream流的收集操作:

收集Stream流的含义:就是把Stream流操作后的结果数据转回到集合或者数组中去

Stream流:方便操作集合/数组的手段

集合/数组:才是开发中的目的

package com.itheima.d7_stream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamTest3 {
    //收集Stream流的数据到集合或者数组中去
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.add("张三丰");
        Stream<String> s1=list.stream().filter(s-> s.startsWith("张"));
        List<String> zhangList=s1.collect(Collectors.toList());
        System.out.println(zhangList);
        //流只能使用一次
        Stream<String> s2=list.stream().filter(s->s.startsWith("张"));
        Set<String> zhang=s2.collect(Collectors.toSet());
        System.out.println(zhang);
    }
}

收集Stream流的作用?

Stream流是操作集合/数组的手段

操作的结果数据最终要恢复到集合或者数组中去

异常处理:

异常概述:异常是程序在"编译"或者"运行的过程中可能出现的问题,注意:语法错误不算在异常体系中

比如:数组索引越界、空指针异常、日期格式化异常,等

为什么要学习异常?

异常一旦出现了,如果没有提前处理,程序就会推出JVM虚拟机而终止

 

1.异常是什么?

异常是代码在编译或者执行的过程中可能出现的错误

2.异常分为几类?

编译时异常,运行时异常

编译时异常:没有继承RuntimeExcpetion的异常, 编译阶段就会报错

运行时异常:继承自RuntimeExcpetion的异常或其子类,编译阶段不报错,运行可能报错

3.学习异常的目的?

避免异常的出现,同时可能出现的异常,让代码更稳健

 编译时异常的特点?

编译时异常:继承自Exception的异常或者其子类

编译阶段报错,必须处理,否则代码不通过

异常的默认处理流程?

默认会出现异常的代码那里自动的创建一个异常对象:ArithmeticException

异常会从方法中出现的点这里抛出给调用者,调用者最终抛出给JVM虚拟机

虚拟机接收到异常对象后,先在控制台直接输出异常栈信息数据

直接从当前的异常点干掉当前程序

后续代码没有机会执行了,因为程序已经死亡了

默认异常处理机制:

默认的异常处理机制不好,一旦真的出现异常,程序立即死亡

编译时异常是编译阶段就会出错的,所以必须处理,否则代价根本无法通过

编译时异常的处理形式有三种:

出现异常直接跑出去给调用者,调用者也继续抛出去

出现异常自己捕获处理,不麻烦别人

前两者结合,出现异常直接抛出去给调用者,调用者捕获处理

异常处理方式:----throws

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

这种方法并不好,发生异常的方法自己不处理异常,如果异常最终跑出去给虚拟机将引起程序死亡

抛出异常格式:

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

规范做法:

方法  throws Exception{}

异常处理方式2---try..catch...

监视捕获异常,用在方法内部,可以将方法内部出现的异常直接捕获处理

这种方式还可以,发生异常的方法自己独立完成异常的处理,程序可以继续往下执行

格式:                                                建议格式:

try{                                                      

 

}catch(异常类型1 变量){                     

}catch(异常类型2 变量){                 

}                                                

异常处理方式3----前两者结合

方法直接将异常通过throwa跑出去给调用者

调用者收到异常后直接捕获处理

运行时异常的处理形式:

运行时异常编译阶段不会出现,是运行时才可能出错的,所以编译阶段不处理也可以

按照规范建议还是处理:建议在最外层调用处集中捕获处理即可

自定义异常的必要?

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

如果企业向通过异常的方式来管理自己的某个业务问题,就需要自定义异常类了

自定义异常的好处:

可以使用异常的机制管理业务问题,提醒程序员注意

同时一旦出现bug,可以用异常的形式清晰的指出出错的地方

自定义异常的分类:

1.自定义编译时异常

2.定义一个异常继承Exception

3.重写构造器

在出现异常的地方用throw new自定义对象抛出

作用:编译时异常是编译阶段就报错,提醒更加强烈,一定需要处理

自定义运行时异常

定义一个异常类继承RuntimeException

重写构造器

在出现异常的地方用throw new 自定义对象抛出

作用:提醒不强烈,编译阶段不报错,运行时才可能出现

举报

相关推荐

Java学习-第21天

学习java第8天

学习java第14天

学习Java第14天

java学习第7天

学习java第12天

Java基础学习第4天

0 条评论