专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

身为java开发人员,这份Java泛型与容器知识点整理你真得好好看看了

容器框架图:

76_1.png

Collection接口

Set接口:Collection的子接口>>无序不可重复 HashSet:Set接口的实现类

List接口:Collection的子接口>>有序可重复

ArrayList:Lis接口t的实现类(数组列表)查询效率高 LinkedList:List接口的实现类(链表)增删效率高 Vector:List接口的实现类(底层是数组)线程安全

Map接口

HashMap:Map接口的实现类

Collection< E >接口常用方法

76_2.png

下面的方法一般用于2个容器间的操作;不过也可以使用1个容器,自己与自己进行交、并、差等操作,一般没这个必要。 注意:2个容器的数据类型必须一致

76_3.png

代码测验如下:

import java.util.ArrayList;
import java.util.Collection;

public class TestCollection {

    public static void main(String[] args) {

        Collection<String> coll = new ArrayList<>();        
        coll.add("1");
        coll.add("2");
        coll.add("3");
        System.out.println(coll);//[1, 2, 3]
        coll.clear();
        System.out.println(coll);//[]

        coll.add("A");
        coll.add("B");
        coll.add("C");
        coll.add("DE");
        System.out.println(coll);//[A, B, C, DE]

//      coll.remove(2);//这里表示的含义是移除整数2,而不是移除数组下标为2的元素
        coll.remove("DE");
        System.out.println(coll);//[A, B, C]

        int a = coll.size();
        System.out.println(a);//3

        boolean b = coll.isEmpty();
        System.out.println(b);//false

        boolean c = coll.contains("A");
        System.out.println(c);//true

        Object[] d = coll.toArray();
        System.out.println(d);//[Ljava.lang.Object;@15db9742

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

        Collection<String> coll02 = new ArrayList<>();
        coll02.add("B");
        coll02.add("C");
        coll02.add("D");
        System.out.println("coll:"+coll);//coll:[A, B, C]
        System.out.println("coll02:"+coll02);//coll02:[B, C, D]

        boolean e = coll.containsAll(coll02);
        System.out.println(e);//false

        coll.retainAll(coll02);
        System.out.println(coll);//[B, C]

        coll.addAll(coll02);
        System.out.println(coll);//[B, C, B, C, D]

        coll.removeAll(coll02);
        System.out.println(coll);//[]

    }

}

List< E >接口常用方法

76_4.png

代码测验如下:

import java.util.ArrayList;
import java.util.List;
/**
 *  List接口中的方法多加了一个索引、下标
 */
public class TestList {

    public static void main(String[] args) {

        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        System.out.println(list);//[1, 2, 3, 4, 5]

        list.add(1,11);
        System.out.println(list);//[1, 11, 2, 3, 4, 5]

//      list.remove(11);//此处默认将11当成下标来运算,而不是将11当成一个元素内容

        list.remove(1);
        System.out.println(list);//[1, 2, 3, 4, 5]

        list.set(0,11);
        System.out.println(list);//[11, 2, 3, 4, 5]

        int a = list.get(0);
        System.out.println(a);//11

        list.add(5);
        list.add(4);
        list.add(3);
        list.add(2);
        list.add(11);

        int b = list.indexOf(11);
        System.out.println(b);//0

        int c = list.lastIndexOf(11);
        System.out.println(c);//9

        List<Integer> list02 = new ArrayList<>();
        list02.add(12);
        list02.add(14);
        list02.add(16);

        list.addAll(1,list02);
        System.out.println(list);//[11, 12, 14, 16, 2, 3, 4, 5, 5, 4, 3, 2, 11]

    }

}

区分Collection接口中的remove方法、List接口中的remove方法

import java.util.ArrayList;
import java.util.List;
/**
 *  区分Collection接口中的remove方法、List接口中的remove方法
 *  
 */
public class TestRemove {

    public static void main(String[] args) {

        List<String> list01 = new ArrayList<>();
        list01.add("1");
        list01.add("2");
        list01.add("3");
        list01.add("4");
        list01.add("5");
        System.out.println(list01);//[1, 2, 3, 4, 5]

        //父接口Collection中的remove方法
        list01.remove("1");
        System.out.println(list01);//[2, 3, 4, 5]

        //List接口中的remove方法
        list01.remove(1);
        System.out.println(list01);//[2, 4, 5]

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

        List<Integer> list02 = new ArrayList<>();
        list02.add(1);
        list02.add(2);
        list02.add(3);
        list02.add(4);
        list02.add(5);
        list02.add(11);

        list02.remove(1);
        System.out.println(list02);//[1, 3, 4, 5, 11]

        /**
         * java.lang.IndexOutOfBoundsException: Index: 11, Size: 5
         */
        list02.remove(11);//此处会报下表越界异常,因为在int类型中它默认指的是下标索引

    }

}

练习一:手写模拟ArrayList创建数组,添加元素功能(加入泛型):

/**
 *  手写ArrayList创建容器,添加元素功能
 *  增加泛型
 */
public class WriteArrayList<E> {

    private Object[] array;
    private int size;//数组下标
    private static final int DEFAULT = 10;

    public WriteArrayList() {
        array = new Object[DEFAULT];
    }

    public WriteArrayList(int index) {
        array = new Object[index];
    }

    public void add(E data) {
        array[size++] = data;
    }

    @Override
    public String toString() {
        //以[a,b,c]格式输出
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for(int i=0; i<size; i++) {
            sb.append(array[i]+",");
        }
        sb.setCharAt(sb.length()-1,']');//将最后输出的逗号','替换为']'符号,代码中的单引号不能更改为双引号
        return sb.toString();
    }

    public static void main(String[] args) {
        WriteArrayList<Integer> wal = new WriteArrayList<>();
        wal.add(11);
        wal.add(12);
        wal.add(13);
        System.out.println(wal);
    }

}

练习二:在练习一的基础上增加数组扩容

/**
 *  增加数组扩容
 */
public class WriteArrayList<E> {

    private static Object[] array;
    private int size;//数组下标
    private static final int DEFAULT = 10;

    public WriteArrayList() {
        array = new Object[DEFAULT];
    }

    public WriteArrayList(int index) {
        array = new Object[index];
    }

    public void add(E data) {
        //什么时候扩容?
        if(size==array.length) {
            //如何扩容?
            Object[] newArray = new Object[array.length+(array.length>>1)];//类比10+10/2,此处注意加号'+'优先级高于'>>'
            System.arraycopy(array, 0, newArray, 0, array.length);
            array = newArray;
        }
        array[size++] = data;
    }

    @Override
    public String toString() {
        //以[a,b,c]格式输出
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for(int i=0; i<size; i++) {
            sb.append(array[i]+",");
        }
        sb.setCharAt(sb.length()-1,']');//将最后输出的逗号','替换为']'符号,代码中的单引号不能更改为双引号
        return sb.toString();
    }

    public static void main(String[] args) {
        WriteArrayList<Integer> wal = new WriteArrayList<>();
        for(int i=0; i<40; i++) {
            wal.add(i);
        }
        System.out.println(wal);
    }

}

练习三:在练习二的基础上增加set()、get()方法,增加数组边界检测

/**
 *  增加set()、get()方法
 *  增加数组边界检查(判断索引是否合法)
 */
public class WriteArrayList<E> {

    private static Object[] array;
    private int size;//数组下标
    private static final int DEFAULT = 10;

    public WriteArrayList() {
        array = new Object[DEFAULT];
    }

    public WriteArrayList(int index) {
        //加入判断
        if(index<0) {
            throw new RuntimeException("容器的容量不能为负数:"+index);
        } else if(index==0) {
            array = new Object[DEFAULT];
        } else {
            array = new Object[index];
        }
    }

    public void add(E data) {
        //什么时候扩容?
        if(size==array.length) {
            //如何扩容?
            Object[] newArray = new Object[array.length+(array.length>>1)];//类比10+10/2,此处注意加号'+'优先级高于'>>'
            System.arraycopy(array, 0, newArray, 0, array.length);
            array = newArray;
        }
        array[size++] = data;
    }

    @Override
    public String toString() {
        //以[a,b,c]格式输出
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for(int i=0; i<size; i++) {
            sb.append(array[i]+",");
        }
        sb.setCharAt(sb.length()-1,']');//将最后输出的逗号','替换为']'符号,代码中的单引号不能更改为双引号
        return sb.toString();
    }

    public E get(int index) {
        checkIndex(index);
        return (E)array[index];
    }

    public void set(int index, E data) {
        checkIndex(index);
//      //索引合法判断,索引区间应满足[0,size)
//      if(index<0||index>size-1) {
//          //不合法,手动抛出异常
//          throw new RuntimeException("索引不合法:"+index);
//      }
        array[index] = data;
    }

    /**
     *  由于许多地方都需要判断index索引是否合法,
     *  所以在此处写一个独立的方法,需要时直接调用即可
     */
    public void checkIndex(int index) {
        //索引合法判断,索引区间应满足[0,size)
        if(index<0||index>size-1) {
            //不合法,手动抛出异常
            throw new RuntimeException("索引不合法:"+index);
        }
    }

    public static void main(String[] args) {
        WriteArrayList<Integer> wal = new WriteArrayList<>();
        for(int i=0; i<40; i++) {
            wal.add(i);
        }
        System.out.println(wal.get(10));

        wal.set(1,100);
        System.out.println(wal);

    }

}

练习四:在练习三的基础上增加remove()、size()、isEmpty()方法的实现

/**
 *  增加2种remove()实现方法
 *  增加size()、isEmpty()方法
 */
public class WriteArrayList<E> {

    private static Object[] array;
    private int size;//数组下标
    private static final int DEFAULT = 10;

    public WriteArrayList() {
        array = new Object[DEFAULT];
    }

    public WriteArrayList(int index) {
        //加入判断
        if(index<0) {
            throw new RuntimeException("容器的容量不能为负数:"+index);
        } else if(index==0) {
            array = new Object[DEFAULT];
        } else {
            array = new Object[index];
        }
    }

    public void add(E data) {
        //什么时候扩容?
        if(size==array.length) {
            //如何扩容?
            Object[] newArray = new Object[array.length+(array.length>>1)];//类比10+10/2,此处注意加号'+'优先级高于'>>'
            System.arraycopy(array, 0, newArray, 0, array.length);
            array = newArray;
        }
        array[size++] = data;
    }

    @Override
    public String toString() {
        //以[a,b,c]格式输出
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for(int i=0; i<size; i++) {
            sb.append(array[i]+",");
        }
        sb.setCharAt(sb.length()-1,']');//将最后输出的逗号','替换为']'符号,代码中的单引号不能更改为双引号
        return sb.toString();
    }

    public E get(int index) {
        checkIndex(index);
        return (E)array[index];
    }

    public void set(int index, E data) {
        checkIndex(index);
//      //索引合法判断,索引区间应满足[0,size)
//      if(index<0||index>size-1) {
//          //不合法,手动抛出异常
//          throw new RuntimeException("索引不合法:"+index);
//      }
        array[index] = data;
    }

    /**
     *  由于许多地方都需要判断index索引是否合法,
     *  所以在此处写一个独立的方法,需要时直接调用即可
     */
    public void checkIndex(int index) {
        //索引合法判断,索引区间应满足[0,size)
        if(index<0||index>size-1) {
            //不合法,手动抛出异常
            throw new RuntimeException("索引不合法:"+index);
        }
    }

    public void remove(int index) {
        //数组中需要移动的元素个数
        int numMoved = array.length - index - 1;
        if(numMoved>0) {
            //底层原理:数组的拷贝
            System.arraycopy(array, index+1, array, index, numMoved);
        }
        array[--size] = null;
    }

    public void remove(E data) {
        for(int i=0; i<size; i++) {
            if(array[i].equals(data)) {
                remove(i);
            }
        }
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size==0?true:false;
    }

    public static void main(String[] args) {
        WriteArrayList<Integer> wal = new WriteArrayList<>();
        for(int i=0; i<40; i++) {
            wal.add(i);
        }
        System.out.println(wal.get(10));

        wal.set(1,100);
        System.out.println(wal);

        wal.remove(2);
        System.out.println(wal);

        WriteArrayList<String> s = new WriteArrayList<String>();
        s.add("A");
        s.add("B");
        s.add("C");
        s.add("D");
        System.out.println(s);
        s.remove(1);
        System.out.println(s);
        s.remove("D");
        System.out.println(s);

        System.out.println(s.size());
        System.out.println(s.isEmpty());
    }

}

学习StringBuilder类,及它提供的append()、setCharAt()方法 掌握数组拷贝arraycopy()方法: System.arraycopy(被复制的数组, 从第几个元素开始复制, 要复制到哪个数组, 粘贴到什么位置, 一共要复制多少个元素); 自己独立重写ArrayList实现类的功能

练习1到4心得:

下面的代码是我独立完成的,与练习4的代码的本质区别是:size和array.length具体代表的含义。 我下面的代码中size代表容器中元素的个数,array.length表示容器大小,由于数组扩容,容器大小一般大于元素个数。 注意==与equals的区别。

public class WriteArrayList02<E> {

    private Object[] array;
    private int size;
    private static final int DEFAULT = 10;

    public WriteArrayList02() {
        array = new Object[DEFAULT];
    }

    public WriteArrayList02(int index) {
        if(index == 0) {
            array = new Object[DEFAULT];
        }else if(index<0) {
            throw new RuntimeException("索引不能为负数:"+index);
        }else {
            array = new Object[index];
        }
    }

    public void add(E element) {
        if(size==array.length) {
            Object[] newArray = new Object[array.length+(array.length>>1)];
            System.arraycopy(array, 0, newArray, 0, array.length);
            array = newArray;
        }
        array[size++] = element;
    }

    public void set(int index, E element) {
        checkIndex(index);
        array[index] = element;
    }

    public E get(int index) {
        checkIndex(index);
        return (E)array[index];
    }

    public void checkIndex(int index) {
        if(index<0||index>=size) {
            throw new RuntimeException("索引异常:"+index);
        }
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        for(int i=0; i<size; i++) {
            sb.append(array[i]+",");
        }
        sb.setCharAt(sb.length()-1,']');
        return sb.toString();
    }

    public void remove(E element) {
        for(int i=0; i<size; i++) {
            if(array[i].equals(element)) {
                remove(i);
            }
        }
    }

    public void remove(int index) {
        System.out.println(array.length);
        //1,2,3,4,5,6,7
        int numCopy = size - index - 1;
        if(numCopy<0) {
            throw new RuntimeException("索引异常:"+index);
        }else if(numCopy==0) {
            array[size] = null;
        }else {
            System.arraycopy(array, index+1, array, index, numCopy);
        }   
        //array[size-1] = null;
        size--;
        System.out.println(array.length);
    }

    public int size() {
        return size;
    }

    public boolean isEmpty() {
        return size==0?true:false;
    }

    public static void main(String[] args) {
        WriteArrayList02<String> wal = new WriteArrayList02<>();
        for(int i=0; i<40; i++) {
            wal.add(i+"");
        }
        System.out.println(wal);

        wal.set(1,"11");
        System.out.println(wal);

        System.out.println(wal.get(39));

        wal.set(39,"12");
        System.out.println(wal);

        wal.remove(0);
        System.out.println(wal);
//      wal.remove(38);
//      System.out.println(wal);
        wal.remove("12");
        System.out.println(wal);
        System.out.println(wal.size());
        System.out.println(wal.isEmpty());
    }

}

LinkedList链表存储结构

76_5.png

最后

感谢你看到这里,看完有什么的不懂的可以在评论区问我,觉得文章对你有帮助的话记得给我点个赞,每天都会分享java相关技术文章或行业资讯,欢迎大家关注和转发文章!

文章永久链接:https://tech.souyunku.com/31129

未经允许不得转载:搜云库技术团队 » 身为java开发人员,这份Java泛型与容器知识点整理你真得好好看看了

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们