一、泛型
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; } }
时间: 2024-10-26 21:40:19