美文网首页程序员
身为java开发人员,这份Java泛型与容器知识点整理你真得好好

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

作者: 程序员伟杰 | 来源:发表于2020-07-28 14:25 被阅读0次

    容器框架图:

    Collection接口

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

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

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

    Map接口

    HashMap:Map接口的实现类

    Collection< E >接口常用方法

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


    代码测验如下:

    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 >接口常用方法

    代码测验如下:

    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链表存储结构

    最后

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

    相关文章

      网友评论

        本文标题:身为java开发人员,这份Java泛型与容器知识点整理你真得好好

        本文链接:https://www.haomeiwen.com/subject/jxjfrktx.html