栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java笔记8

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java笔记8

目录

一、异常

1.try…catch

①Throwable类

②多catch并行处理

2.throw和throws关键字的使用

3.finally代码块

4.Runtime异常

编译异常 :

运行异常 :

常见的运行异常:

5.自定义异常

二、集合框架

1.集合框架由来

2.集合框架的继承体系

①Collection (集合) 接口  单列集合

②Map (映射键值对) 接口  双列集合

③Iterator迭代器接口

④泛型 Generic

⑤for(:)循环

3.Collection接口

①定义

②Collection接口的常用方法

 4.Iterator接口

①定义

②Iterator接口的抽象方法

②获取迭代器接口实现类

④迭代器的实现原理

⑤并发修改异常

⑥集合存储自定义对象并迭代

5.List接口

①特点

②List接口自己的方法 (带有索引)

③List集合的特有迭代器

6.List接口的实现类的数据结构

数组 :

链表

三、集合

1.ArrayList

①特点

②源码解析

2.linkedList

①linkedList集合的特点

②linkedList集合特有方法

③源码解析

3.Set集合

①Set接口实现类HashSet类

③对象的哈希值

④String类的哈希值

 ⑤哈希值的相关问题

⑥哈希表的数据结构

⑦哈希表存储对象的过程

4.红黑树(Red-Black-Tree)

二叉树,本质就是链表

自然平衡二叉树

红黑树

①TreeSet集合使用

②TreeSet存储自定义对象

5.linkedHashSet

6.Collections工具类


一、异常

1.try…catch

public static void main(String[] args) {
        int[] arr = {1};
        //try  catch异常处理
        try {
            int i = getNum(arr);
            System.out.println("i = " + i);
        }catch (Exception ex){
            System.out.println("异常被处理掉");
        }
        System.out.println(111);
    }

    public static int getNum(int[] arr){
        return arr[1] + 10;
    }

①Throwable类
public static void main(String[] args){
        int[] arr = {1};
        //try catch异常处理
        try{
            int i = getNum(arr);
            System.out.println("i=" + i);
        }catch (Exception ex){
            //Throwable类的异常信息的方法
            String message = ex.getMessage();//message=1
            System.out.println("message=" + message);

            String str = ex.toString();//str = java.lang.ArrayIndexOutOfBoundsException: 1
            System.out.println("str=" + str);
            
            ex.printStackTrace();
        }

        System.out.println(111);
    }

    public static int getNum(int[] arr){
        return arr[1] + 10;
    }

②多catch并行处理

异常处理的代码中,try可以跟随多个catch

好处:不同的异常,可以区别对待,分开处理

注意:如果catch中的异常类没有关系,先写后写没有区别;catch中的异常类有继承关系,父类写在最下面

2.throw和throws关键字的使用

throw关键字 : 只能写在方法内部, 关键字的后面跟随对象的创建

throws关键字 : 只能写在方法的定义上,关键字后面跟随异常类名

public static void main(String[] args) {
       
    try {
        int area = getArea(-10);
        System.out.println(area);
    } catch (Exception e) {
        e.printStackTrace();
    }
}


public static int getArea(int length) throws  Exception{
    if (length <= 0)
        //数据错误,导致后面的计算不能进行
        //内部出现问题
        throw new Exception("边长不存在");
    return length * length;
}

3.finally代码块

finally代码块跟随try ... catch使用,也有跟随try使用,finally代码块里面的程序,无论是否出现异常,都会执行,必须执行,结束JVM了,finally不执行

作用:主要用于释放资源

public static void main(String[] args) {
    try {
        int[] arr = {1};
        System.out.println(arr[0]);
    }catch (Exception ex){
        ex.printStackTrace();
    }finally {
        //后期用于资源的释放
        System.out.println("这里的代码,必须执行");
    }
}

4.Runtime异常

        异常的父类是Exception,Exception类的子类RuntimeException,凡是RuntimeException和他的所有子类,都称为运行异常,非子类的称为编译异常Exception异常

编译异常 :

方法出现编译异常,调用者必须处理,否则编译失败.处理方式可以是try catch或者是throws都可以

运行异常 :

方法出现运行异常,方法的定义上,不需要throws声明,调用者也不需要处理这个异常

常见的运行异常:

NullPointerException空指针

IndexOutOfBoundsException越界异常

ClassCastException类型强制

IllegalArgumentException无效的参数异常

5.自定义异常

自定义异常,入伙,继承Exception或者RuntimeException

只有Exception和他的子类,才具有可抛出性

自定义的类中,构造方法,super调用父类构造方法,传递异常信息

自定义的异常类:

        成绩负数的异常

        自定义异常信息 : 继承父类 RuntimeException 带有String类型的构造方法 (String 异常信息)

public class ScoreException extends RuntimeException{
    public ScoreException(String s){
        super(s);
    }
}
public static void main(String[] args) {
       // int[] arr = {1};
        //System.out.println(arr[2]);
        int avg = getAvg(-100,2);
        System.out.println("avg = " + avg);
    }

    
    public static int getAvg(int math,int chinese){
        //判断成绩的数值
        if ( math < 0 || chinese < 0)
            //手动抛出,自己定义的异常
            throw new ScoreException("成绩不存在");

        return  (math + chinese) / 2;
    }

二、集合框架

1.集合框架由来

①集合本质上是存储对象的容器

②数组也能存储对象,数组弊端就是定长

③解决数组的问题,开发出来集合框架,集合框架无需考虑长度

④集合和数组的区别与共同点

        集合,数组都是容器,都可以存储数据

        集合只存储引用数据类型,不存储基本数据类型

        数组可以存储基本类型,也可以存储引用类型

        数组定长,集合容器变成

数据多了存数组,对象多了存集合

2.集合框架的继承体系

①Collection (集合) 接口  单列集合

List (列表) 接口

        ArrayList (数组列表) 实现类

        linkedList (链表) 实现类

        Vector(数组列表) 实现类,过时了

Set (集) 接口

        HashSet(哈希表) 实现类

        linkedHashSet(链表哈希表) 实现类,继承HashSet

        TreeSet(红黑树) 实现类

②Map (映射键值对) 接口  双列集合

  - HashMap(哈希表) 实现类

    - linkedHashMap(链表哈希表) 实现类,继承HashMap

  - TreeMap(红黑树) 实现类

  - Hashtable(哈希表) 实现类,过时

    - Properties(哈希表)实现类, 继承Hashtable

  - ConCurrentHashMap (哈希表) 线程相关

③Iterator迭代器接口

④泛型 Generic

  - 写法

  - 泛型类,泛型方法,泛型接口,泛型限定,泛型通配符

⑤for(:)循环

3.Collection接口

①定义

是所有单列集合的顶级接口,任何单列集合都是他的子接口,或者是实现类, 该接口中定义的方法,是所有单列集合的共性方法

Collection  尖括号就是泛型,E我们要写,集合存储的数据类型

②Collection接口的常用方法

方法的定义

方法作用

boolean add(E)

元素添加到集合

void clear()

清空集合容器中的元素

boolean contains(E)

判断元素是否在集合中

boolean isEmpty()

判断集合的长度是不是0,是0返回true

int size()

返回集合的长度,集合中元素的个数

boolean remove(E)

移除集合中指定的元素,移除成功返回true

T[] toArray(T[] a)

集合转成数组

 4.Iterator接口 ①定义

迭代器接口 Iterator , 为集合进行遍历的.。迭代器技术是所有Collection集合的通用遍历形式

②Iterator接口的抽象方法

②获取迭代器接口实现类

迭代器就是为了遍历集合而产生.。

集合的顶层接口Collection中定义了方法: iterator() ,返回值是Iterator接口类型, 返回的是Iterator接口实现类的对象

Collection接口中的方法摘要 :public Iterator iterator() ; 返回迭代器接口实现类的对象

使用的对象ArrayList,实现接口Collection,重写方法iterator();

public static void main(String[] args) {
    //迭代器遍历集合
    //接口多态创建集合容器对象,存储的数据类型是字符串
    Collection coll = new ArrayList<>();
    //集合对象的方法add添加元素
    coll.add("hello");
    coll.add("world");
    coll.add("java");
    coll.add("money");
    coll.add("wife");
    //1 遍历 集合对象,调用方法iterator() 获取迭代器接口的实现类对象
    Iterator it = coll.iterator();
    //2 迭代器对象的方法,判断集合是否有下元素
    //boolean b = it.hasNext();
    //System.out.println(b);
    //3 迭代器对象的方法,取出元素
    //String str = it.next();
    //System.out.println(str);
    //条件,集合中有下一个元素就可以
    while ( it.hasNext() ){
        String str =  it.next();
        System.out.println(str);
    }
}

④迭代器的实现原理

每个集合容器,内部结构不同,但是迭代器都可以进行统一的遍历实现

结论:迭代器是隐藏在集合的内部的, 提供公共的访问方式, Iterator接口

⑤并发修改异常

异常的产生原因 : 在迭代器遍历集合的过程中,使用了集合的功能,改变了集合的长度造成

public static void main(String[] args) {
    //迭代器遍历集合
    //接口多态创建集合容器对象,存储的数据类型是字符串
    Collection coll = new ArrayList<>();
    //集合对象的方法add添加元素
    coll.add("hello");
    coll.add("world");
    coll.add("java");
    coll.add("money");
    coll.add("wife");
    //迭代器遍历集合
    Iterator it = coll.iterator();
    while ( it.hasNext() ){
        String str = it.next();
        //判断,遍历到的集合元素是不是java
        if (str.equals("java")){
            //添加元素 出现并发修改异常
            coll.add("add");
        }
        System.out.println(str);
    }
}

⑥集合存储自定义对象并迭代
public static void main(String[] args) {
    //创建集合,存储自定义的对象
    Collection coll = new ArrayList<>();
    //集合的方法add存储Person对象
    coll.add( new Person("张三",21) );
    coll.add( new Person("李四",22) );
    coll.add( new Person("王五",23) );
    //迭代器遍历集合

    Iterator iterator = coll.iterator();
    while (iterator.hasNext()){
        Person person = iterator.next();
        System.out.println(person);
        System.out.println(person.getName());
    }
}
public class Person   {
    private String name;
    private int age;
    public Person(){}

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }
}

5.List接口

①特点

这个接口的集合都具有索引

这个接口中的元素允许重复

这个接口中的元素是有序的

元素不会排序 ,有序指的是 ,元素存储和取出的顺序是一致的

②List接口自己的方法 (带有索引)

add(int index ,E e)

指定的索引位置,添加元素

public static void listAdd(){
    List list = new ArrayList<>();
    list.add("a") ;//集合的尾部添加
    list.add("b");
    list.add("c");
    list.add("d");
    list.add("e");
    System.out.println(list);
    //指定的索引上,添加元素 ,3索引添加元素
    list.add(3,"QQ");
    System.out.println(list);
}

get(int index)

返回指定索引上的元素

public static void listGet(){
        List list = new ArrayList<>();
        list.add("a") ;//集合的尾部添加
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");
        //List接口方法get取出元素
        //String s = list.get(3);
        //System.out.println(s);
        for(int i = 0 ; i < list.size() ; i++){
            System.out.println(list.get(i));
        }
    }

set(int index,E e)

修改指定索引上的元素,返回被修改之前的元素

remove(int index)

移除指定索引上的元素, 返回被移除之前的元素

public static void listSetRemove(){
        List list = new ArrayList<>();
        list.add("a") ;//集合的尾部添加
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");
        System.out.println(list);
        //修改指定索引上的元素,3索引
        String str = list.set(3,"https://www.baidu.com");
        System.out.println(list);
        System.out.println(str);
        //删除指定索引上的元素,删除3索引
        str = list.remove(3);
        System.out.println(list);
        System.out.println(str);
    }

③List集合的特有迭代器

List接口中的方法 listIterator() 返回迭代器,迭代器的接口是ListIterator,集合的专用迭代器.

ListIterator迭代器接口的方法

        boolean hasNext()

        E next()

        boolean hasPrevious() 判断集合中是否有上一个元素,反向遍历

        E previous() 取出集合的上一个元素

6.List接口的实现类的数据结构

 

数组 :

有索引,数组中元素的地址是连续,查询速度快

数组的长度为固定,新数组创建,数组元素的复制,增删的效率慢

链表

链表没有索引,采用对象之间内存地址记录的方式存储

查询元素,必须通过第一个节点依次查询,查询性能慢

增删元素,不会改变原有链表的结构,速度比较快

三、集合

1.ArrayList ①特点

ArrayList类实现接口List,ArrayList具备了List接口的特性:有序,重复,索引

ArrayList集合底层的实现原理是数组,大小可变

数组的特点 : 查询速度快,增删慢

数组的默认长度是10个,每次的扩容是原来长度的1.5倍

ArrayList是线程不安全的集合,运行速度快

②源码解析

ArrayList类成员变量

private static final int DEFAULT_CAPACITY = 10; //默认容量

private static final Object[] EMPTY_ELEMENTDATA = {};//空数组

transient Object[] elementData; //ArrayList集合中的核心数组

private int size; //记录数组中存储个数

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; //数组扩容的最大值

ArrayList集合类的构造方法

无参数构造方法

public ArrayList() {
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; //数组没有长度

有参数的构造方法

public ArrayList(int 10) {
    if (initialCapacity > 0) {
        //创建了10个长度的数组
    	this.elementData = new Object[10];
    } else if (initialCapacity == 0) {
    	this.elementData = EMPTY_ELEMENTDATA;
    } else {
    	throw new IllegalArgumentException("Illegal Capacity: "+
    initialCapacity);
    }
}

ArrayList集合类的方法add() 

new ArrayList<>().add("abc"); //集合中添加元素
public boolean add("abc") {
    //检查容量  (1)
    ensureCapacityInternal(size + 1); 
    //abc存储到数组中,存储数组0索引,size计数器++
    elementData[size++] = "abc";//数组扩容为10
    return true;
}
//检查集合中数组的容量, 参数是1
private void ensureCapacityInternal(int minCapacity = 1) {
    //calculateCapacity 计算容量,方法的参是数组 , 1
    // ensureExplicitCapacity (10) 扩容的
    ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
//计算容量方法, 返回10
private static int calculateCapacity(Object[] elementData, int minCapacity = 1) {
    //存储元素的数组 == 默认的空的数组  构造方法中有赋值
    if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
        //返回最大值   max(10,1)
    	return Math.max(DEFAULT_CAPACITY, minCapacity);
    }
    return minCapacity;
}
//扩容 
private void ensureExplicitCapacity(int minCapacity = 10) {
    modCount++;
   // 10 - 数组的长度0 > 0
    if (minCapacity - elementData.length > 0)
        //grow方法(10) 数组增长的
    	grow(minCapacity);
}
//增长的方法,参数是(10)
 private void grow(int minCapacity = 10) {
     //变量oldCapacity保存,原有数组的长度  = 0
     int oldCapacity = elementData.length; // 0
     //新的容量 = 老 + (老的 / 2)
     int newCapacity = oldCapacity + (oldCapacity >> 1);// 0
     // 0 - 10 < 0 新容量-计算出的容量
     if (newCapacity - minCapacity < 0)
     	newCapacity = minCapacity; //新容量 = 10
     //判断是否超过最大容量
     if (newCapacity - MAX_ARRAY_SIZE > 0)
     newCapacity = hugeCapacity(minCapacity);
     // minCapacity is usually close to size, so this is a win:
//数组的赋值,原始数组,和新的容量
     elementData = Arrays.copyOf(elementData, newCapacity);
 }

2.linkedList

①linkedList集合的特点

linkedList类实现接口List,linkedList具备了List接口的特性:有序,重复,索引

linkedList底层实现原理是链表,双向链表

linkedList增删速度快

linkedList查询慢

linkedList是线程不安全的集合,运行速度快

②linkedList集合特有方法

集合是链表实现,可以单独操作链表的开头元素和结尾元素

void addFirst(E e) 元素插入到链表开头

void addLast(E e) 元素插入到链表结尾

E getFirst() 获取链表开头的元素

E getLast() 获取链表结尾的元素

E removeFirst() 移除链表开头的元素

E removeLast() 移除链表结尾的元素

void push(E e)元素推入堆栈中

E pop()元素从堆栈中弹出

③源码解析

linkedList集合的成员变量

transient int size = 0; //集合中存储元素个数计数器

transient Node first; //第一个元素是谁

transient Node last; //最后一个元素是谁

 linkedList集合的成员内部类Node (节点)

private static class Node {
        E item; //我们存储的元素
        Node next; // 下一个节点对象
        Node prev; // 上一个节点对象
    //构造方法,创建对象,传递上一个,下一个,存储的元素
    Node(Node prev, E element, Node next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
}

 linkedList集合的方法add()添加元素

void linkLast(E "abc") {
    //声明新的节点对象 = last
    final Node l = last; // l = null  l "abc"节点
    //创建新的节点对象,三个参数, 最后一个对象,"abc", 上一个对象null
    final Node newNode = new Node<>(l, e, null);
    //新节点赋值给最后一个节点
    last = newNode;
    if (l == null)
        //新存储的几点赋值给第一个节点
    	first = newNode;
    else
    	l.next = newNode;
    size++;
    modCount++;
}

3.Set集合

Set集合,是接口Set,继承Collection接口,Set集合不存储重复元素

Set接口下的所有实现类,都会具有这个特性

Set接口的方法,和父接口Collection中的方法完全一样

①Set接口实现类HashSet类

HashSet集合类的特点

        实现Set接口,底层调用的是HashMap集合

        HashSet的底层实现原理是哈希表

        HashSet不保证迭代顺序,元素存储和取出的顺序不一定

        线程不安全,运行速度快

③对象的哈希值

每个类继承Object类,Object类定义方法 :

public native int hashCode(); // C++语言编写,不开源

 方法使用没有区别 : 方法返回int类型的值,就称为哈希值

④String类的哈希值

字符串类重写方法hashCode(),自定义了哈希值,哈希值的计算方法是 :

h = 31 * 上一次的计算结果 + 字符数组中元素的ASCII码值

        *31 的目的,减少相同哈希值的计算

 ⑤哈希值的相关问题

两个对象的哈希值相同,不要求equals一定返回true. 两个对象的equals返回true,两个对象的哈希值必须一致

⑥哈希表的数据结构

数组 + 链表的组合体

class Node{
    E element; //存储的元素
    Node next; //下一个元素
}
main(){
    Node[] node = new Node[5];
}

 哈希表的底层数组长度默认是16个,扩容为原来长度的2倍

加载因子默认是0.75F,数组中存储元素的个数达到长度的75%,扩容

⑦哈希表存储对象的过程

4.红黑树(Red-Black-Tree)

二叉树,本质就是链表

        查询速度快

        每个一个节点,只有两个子节点,左和右

        树长偏了

自然平衡二叉树

        二叉树的基础上,改进,保证树是平衡的

红黑树

        每个节点有颜色,要么红,要么是黑

        根节点必须是黑色

        叶子节点必须是黑色

        变量表示颜色,true黑色,false红色

①TreeSet集合使用

TreeSet集合,底层是红黑树结构,依赖于TreeMap的实现

可以对存储到红黑树的元素进行元素的自然顺序排序

②TreeSet存储自定义对象
public static void treeSetStudent(){
    Set set = new TreeSet();
    set.add(new Student("a",10));
    set.add(new Student("b",20));
    System.out.println("set = " + set);
}

  程序出现了异常,类型的转换异常 ClassCastException

异常原因,Student类不能进行类型的转换,有接口没有实现java.lang.Comparable.

类实现接口Comparable,这个类就具有了自然顺序

 Student类具有自然顺序

实现接口Comparable,重写方法compareTo

 
    public int compareTo(Student student){
        return this.age - student.age;
    }

 自定义比较器java.util.Comparator接口

public class MyCom implements Comparator {
    @Override
    
    public int compare(Student o1, Student o2) {
        return o1.getAge() - o2.getAge();
    }
}
 Set set = new TreeSet( new MyCom());

5.linkedHashSet

底层的数据结构是哈希表,继承HashSet

linkedHashSet数据是双向链表, 有序的集合,存储和取出的顺序一样

public static void main(String[] args) {
    Set set = new linkedHashSet<>();
    set.add("b");
    set.add("e");
    set.add("c");
    set.add("a");
    set.add("d");
    System.out.println("set = " + set);
}

6.Collections工具类

java.util.Collection 集合的顶级接口

 java.util.Collections 操作集合的工具类

工具类的方法全部静态方法,类名直接调用

主要是操作Collection系列的单列集合,少部分功能可以操作Map集合

public class CollectionsTest {
    public static void main(String[] args) {
        sort2();
    }
    //集合元素的排序,逆序
    public static void sort2(){
        List list = new ArrayList();
        list.add(1);
        list.add(15);
        list.add(5);
        list.add(20);
        list.add(9);
        list.add(25);
        System.out.println("list = " + list);
        //Collections.reverseOrder() 逆转自然顺序
        Collections.sort(list,Collections.reverseOrder());
        System.out.println("list = " + list);
    }
    //集合元素的排序
    public static void sort(){
        List list = new ArrayList();
        list.add(1);
        list.add(15);
        list.add(5);
        list.add(20);
        list.add(9);
        list.add(25);
        System.out.println("list = " + list);
        Collections.sort(list);
        System.out.println("list = " + list);
    }

    //集合元素的随机交换位置
    public static void shuffle(){
        List list = new ArrayList();
        list.add(1);
        list.add(15);
        list.add(5);
        list.add(20);
        list.add(9);
        list.add(25);
        System.out.println("list = " + list);
        Collections.shuffle(list);
        System.out.println("list = " + list);

    }

    //集合的二分查找
    public static void binarySearch(){
        List list = new ArrayList();
        list.add(1);
        list.add(5);
        list.add(9);
        list.add(15);
        list.add(20);
        list.add(25);
        int index = Collections.binarySearch(list, 15);
        System.out.println(index);
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/763764.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号