zoukankan      html  css  js  c++  java
  • 自定义Java集合

    一、泛型

    1、在JDK1.4以前,所有的集合元素全都按照Object来存储,拿出来还要进行强制转型。由于这样的做法有太多的缺点,容易出现ClassCaseException,不安全,让人不省心,于是乎JDK5之后出现了泛型。

    2、什么是泛型,通俗的讲,就是在Java文件编译期对类型进行检查。比如:List<String> string = new ArrayList<String>(); 它只能装String类型的对象,否则编译时报错。

    二、自定义ArrayList

    1、ArrayList顾名思义,底层就是使用数组实现的List。

    2、代码

    package com.collection.arrayList;
    
    import java.util.Arrays;
    import java.util.Iterator;
    import java.util.NoSuchElementException;
    
    //实现Iterable接口,就可以使用forEach
    public class MyArrayList<E> implements Iterable<E> { //Object的数组,Java没有泛型数组 private Object[] elementData = null; private int size = 0;
      //默认的数组大小是10
    public MyArrayList() { this(10); } public MyArrayList(int cacaptiy) { elementData = new Object[cacaptiy]; } public boolean add(E obj) { //如果当前元素个数已经跟数组一样大了,就扩容 if(size >= elementData.length) { this.ensureCapacityInternal(elementData.length); } elementData[size++] = obj; return true; } @SuppressWarnings("unchecked") public <T> T[] toArray(T[] arr) { if(arr.length < size) { return (T[]) Arrays.copyOf(elementData, size, arr.getClass()); } System.arraycopy(elementData, 0, arr, 0, arr.length); if(arr.length > size) { arr[size] = null; } return arr; } @SuppressWarnings("unchecked") public E[] toArray() { return (E[]) Arrays.copyOf(elementData, elementData.length); } public boolean addAll(MyArrayList<E> list) { for(int i = 0; i < list.size; i++) { this.add(list.get(i)); } return true; } public boolean set(int index, E obj) { if(index < 0 || index >= size) { throw new IndexOutOfBoundsException(); } ensureCapacityInternal(1); System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = obj; size ++; return true; } public boolean remove(int index) { if(index < 0 || index >= size) { throw new ArrayIndexOutOfBoundsException(); } System.arraycopy(elementData, index + 1, elementData, index, size - index -1); size --; return true; } public boolean remove(E obj) { for(int i = 0; i < elementData.length; i++) { if(obj == elementData[i]) { System.arraycopy(elementData, i + 1, elementData, i, size - i - 1); size --; return true; } else if(obj.equals(elementData[i]) && obj.hashCode() == elementData[i].hashCode()) { System.arraycopy(elementData, i + 1, elementData, i, size - i - 1); size --; return true; } } return false; } @SuppressWarnings("unchecked") public E get(int index) { if(index < 0 || index >= size) { throw new ArrayIndexOutOfBoundsException(); } return (E) elementData[index]; } public void ensureCapacityInternal(int cacaptiy) { Object[] newArr = new Object[elementData.length + cacaptiy]; System.arraycopy(elementData, 0, newArr, 0, elementData.length); elementData = newArr; } public int size() { return size; } public boolean isEmpty() { return size == 0; } public void clear() { for(int i = 0; i <size; i++) { elementData[i] = null; } size = 0; } public Iterator<E> iterator() { return new Itr(); } private class Itr implements Iterator<E>{ private int cursor = 0; private int lastRet = -1; @Override public boolean hasNext() { return cursor != size(); } @SuppressWarnings("unchecked") @Override public E next() { if(cursor == size()) { throw new NoSuchElementException(); } lastRet = cursor; return (E) elementData[cursor ++]; } public void remove() { if(lastRet == -1) { throw new IllegalStateException(); } MyArrayList.this.remove(lastRet); cursor = lastRet; lastRet = -1; } } }

    三、自定义LinkedList

    1、LinkedList底层是用链表实现的

    2、先定义一个Node类

    package com.collection.linkedList;
    
    public class Node {
        //前一个节点的引用
        private Node prev;
        //存储的数据
        private Object object;
        //下一个节点的引用
        private Node next;
    
        public Node getPrev() {
            return prev;
        }
    
        public void setPrev(Node prev) {
            this.prev = prev;
        }
    
        public Object getObject() {
            return object;
        }
    
        public void setObject(Object object) {
            this.object = object;
        }
    
        public Node getNext() {
            return next;
        }
    
        public void setNext(Node next) {
            this.next = next;
        }
        
        
        
        
        
    }

    3、MyLinkedList.java

    package com.collection.linkedList;
    
    public class MyLinkedList<E> {
        
        private Node header;//链表的节点头
    
        private Node tail;//链表的结尾
        
        private int size;//记录当前元素的大小
        
        public MyLinkedList() {
            
            
        }
        /**
         * 在某个位置插入元素
         * @param index
         * @param obj
         */
        public void set(int index, E obj) {
            if(index < 0 || index >= size) {
                throw new IndexOutOfBoundsException();
            }
            Node node = new Node();
            node.setObject(obj);
            Node temp1 = header;
            Node temp = null;
            Node temp2 = tail;
            Node prev = null;
            //除以,看看这个index离header近还是tail近
            if(index >= (size >> 1)) {
                
                for(int i = 0; i < index; i++) {
                    temp1 = temp1.getNext();
                }
                temp = temp1;
            } else {
                for(int i = 0; i < size - index - 1; i++) {
                    temp2 = temp2.getPrev();
                }
                temp = temp2;
            }
            prev = temp.getPrev();
            if(prev != null) {
                
                prev.setNext(node);
                
            } else {
                header = node;
            }
            node.setNext(temp);
            temp.setPrev(node);
            size ++;
        }
        
        public boolean remove(int index) {
            if(index < 0 || index >= size) {
                throw new IndexOutOfBoundsException();
            }
            
            Node temp = header;
            
            for(int i = 0; i < index; i++) {
                temp = temp.getNext();
                
            }
            Node prev = temp.getPrev();
            Node next = temp.getNext();
            if(prev != null) {
                
                prev.setNext(next);
            } else {
                
                header = next;
            }
            if(next != null) {
                
                next.setPrev(prev);
            } else {
                
                tail = prev;
            }
            size --;
            return true;
            
        }
        
        public boolean remove(Object obj) {
            if(obj == null) {
                
                return false;
            }
            Node temp = header;
            Node prev = null;
            Node next = null;
            
            while(temp != null) {
                if(temp.getObject() == obj) {
                    
                    prev = temp.getPrev();
                    next = temp.getNext();
                    if(prev != null) {
                        
                        prev.setNext(next);
                    } else {
                        header = next;
                        
                    }
                    if(next != null) {
                        
                        next.setPrev(prev);
                    } else {
                        tail = prev;
                    }
                    size --;
                    return true;
                    
                } else if(temp.getObject().equals(obj) && obj.hashCode() == temp.getObject().hashCode()) {
                    
                    prev = temp.getPrev();
                    next = temp.getNext();
                    if(prev != null) {
                        
                        prev.setNext(next);
                    } else {
                        
                        header = next;
                    }
                    if(next != null) {
                        
                        next.setPrev(prev);
                    } else {
                        tail = prev;
                    }
                    size --;
                    return true;
                } 
                temp = temp.getNext();
            }
            
            return false;
            
        }
        
        
        public boolean add(E obj) {
            Node node = new Node();
            node.setObject(obj);
            if(header == null) {
                header = node;
                header.setPrev(null);
                tail = node;
                node.setNext(null);
                
            } else {
                node.setPrev(tail);
                tail.setNext(node);
                tail = node;
                node.setNext(null);
                
                
            }
            size ++;
            return true;
        }
        
        @SuppressWarnings("unchecked")
        public E get(int index) {
            if(index < 0 || index >= size) {
                throw new IndexOutOfBoundsException();
            }
            
            Node temp = header;
            
            for(int i = 0; i < index; i++) {
                temp = temp.getNext();
                
            }
            
            return (E) temp.getObject();
        }
        
        public int size() {
            
            return size;
        }
    
    }

    四、自定义HashMap

    1、HashMap的底层是用数组和链表实现的,数组的元素是链表,链表里存的是键值对对象

    2、键值对类MyEntry.java

    package com.collection.hashMap;
    
    public class MyEntry {
        
        private Object key;//
        
        private Object value;//
        
        public MyEntry(Object key, Object value) {
            this.key = key;
            this.value = value;
            
        }
    
        public Object getKey() {
            return key;
        }
    
        public void setKey(Object key) {
            this.key = key;
        }
    
        public Object getValue() {
            return value;
        }
    
        public void setValue(Object value) {
            this.value = value;
        }
        
        
    
    }

    3、MyHashMap.java

    package com.collection.hashMap;
    
    import java.util.LinkedList;
    
    /**
     * hashmap是由数组和链表一起构成的
     * 由于使用的是hashCode,顺序不能保证,它是无顺序的。
     * @author may
     *
     * @param <E>
     * @param <U>
     */
    public class MyHashMap<E, U> {
        
        private Object[] elementData = null;
        
        private int size;
        
        private int cacaptiy = 10;
        
        public MyHashMap() {
            
            elementData = new Object[cacaptiy];
        }
        
        
        
        @SuppressWarnings("unchecked")
        public boolean put(E key, U value) {
            int hashCode = Math.abs(key.hashCode());
            MyEntry entry = new MyEntry(key, value);
            LinkedList<MyEntry> linkedList = (LinkedList<MyEntry>) elementData[hashCode % cacaptiy]; 
            //key的hashCode可能会重复,需要做判断
            if(linkedList != null) {
                boolean flag = false;
                for(int i = 0; i < linkedList.size(); i++) {
                    if(linkedList.get(i).getKey().equals(key)) {
                        
                        linkedList.get(i).setValue(value);
                        flag = true;//return;
                        break;
                    }
                } 
                if(!flag) {
                    
                    linkedList.add(entry);
                    size ++;
                }
                
            } else {
                linkedList = new LinkedList<MyEntry>();
                linkedList.add(entry);
                if(size == cacaptiy) {
                    esureCacaptiy(cacaptiy);
                }
                elementData[hashCode % cacaptiy] = linkedList;
                size ++;
            }
            
            
            return true;
        }
        
        public void esureCacaptiy(int increment) {
            Object[] obj = new Object[cacaptiy + increment];
            cacaptiy = cacaptiy + increment;
            System.arraycopy(elementData, 0, obj, 0, elementData.length);
            elementData = obj;
        }
        
        @SuppressWarnings("unchecked")
        public U get(E key) {
            int hashCode = key.hashCode();
            LinkedList<MyEntry> linkedList = (LinkedList<MyEntry>) elementData[hashCode % cacaptiy]; 
            if(linkedList != null) {
                
                for(int i = 0; i < linkedList.size(); i++) {
                    if(linkedList.get(i).getKey().equals(key)) {
                        
                        return (U) linkedList.get(i).getValue();
                        
                    }
                    
                }
                
            }
            
            return null;
            
        }
        
        public int size() {
            
            return size;
        }
        
    
    }

    五、自定义HashSet

    1、HashSet的底层用的是HashMap,它保存的值就是HashMap里的key

    2、代码

    package com.collection.hashSet;
    
    import java.util.HashMap;
    
    /**
     * HashSet底层是用HashMap实现的,是无序的
     * @author may
     *
     * @param <K>
     */
    public class MyHashSet<K> {
        
        private HashMap<K, Object> map = null;
        
        //map的值是固定的
        private final static Object PRESENT = new Object();
        
        public boolean add(K obj) {
            map.put(obj, PRESENT);
            return true;
            
        }
        
        public boolean remove(K obj) {
            map.remove(obj);
            
            return true;
        }
        
    }
  • 相关阅读:
    [I cannot be cast to java.lang.Comparable
    关于有参构造的调用问题
    方法中的参数问题
    mybatis中xml的sql语句传入参数的不同用的#{}中的参数也不相同
    javaweb中向集合中添加对象报空指针异常问题的可能原因
    找不到log4j类的问题可能的原因
    快速失败和安全失败(别人写的,摘抄过来了)
    自动生成的列在xml中写sql代码插入时不写入,但是其余属性要都列出来
    JQ高级
    JQ初级
  • 原文地址:https://www.cnblogs.com/honger/p/6002402.html
Copyright © 2011-2022 走看看