ArrayList和HashMap如何自己實(shí)現(xiàn)實(shí)例詳解
ArrayList和HashMap
ArrayList的存儲(chǔ)就是一個(gè)數(shù)組,
HashMap的存儲(chǔ)是一個(gè)數(shù)組加一個(gè)鏈表,
以下實(shí)現(xiàn)的MyArrayList及MyHashMap,在實(shí)際的工作中都是用不上的,最有可能用得到的地方就是面試找工作以及忽悠別人了。工作中雖然用不上,但是并不代表沒(méi)有用,它可以幫助我們?nèi)ダ斫馑麄兊膶?shí)現(xiàn)原理,等實(shí)現(xiàn)完后再去仔細(xì)查看JDK中的源碼,就會(huì)發(fā)現(xiàn)別人實(shí)現(xiàn)當(dāng)中那些可供學(xué)習(xí)的地方。
MyArrayList
public class MyArrayList<E> { private int capacity = 10; private int size = 0; private E[] values = null; @SuppressWarnings("unchecked") public MyArrayList() { values = (E[]) new Object[capacity]; } @SuppressWarnings("unchecked") public MyArrayList(int capacity) { this.capacity = capacity; values = (E[]) new Object[this.capacity]; } public void put(E e) { if (e == null) { throw new RuntimeException("The value should not be null."); } if (size >= capacity) { enlargeCapacity(); } values[size] = e; size++; } public E get(int index) { if (index >= size) { throw new RuntimeException("The index:" + index + " is out of band."); } return values[index]; } public void remove(int index) { if (index >= size) { throw new RuntimeException("The index:" + index + " is out of band."); } for (int i = index; i < size - 1; i++) { values[i] = values[i + 1]; } values[size - 1] = null; size--; } @SuppressWarnings("unchecked") private void enlargeCapacity() { capacity = capacity * 2; E[] tmpValues = (E[]) new Object[capacity]; System.arraycopy(values, 0, tmpValues, 0, size); values = tmpValues; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("["); for (int i = 0; i < size; i++) { sb.append(values[i]).append(","); } if (size > 0) { sb.deleteCharAt(sb.length() - 1); } sb.append("]"); return sb.toString(); } /** * @param args */ public static void main(String[] args) { MyArrayList<String> myList = new MyArrayList<String>(); myList.put("1"); myList.put("2"); myList.put("3"); myList.put("4"); myList.put("5"); myList.put("6"); myList.put("7"); myList.put("8"); myList.put("9"); myList.remove(7); System.out.println(myList.toString()); } }
MyHashMap
public class MyHashMap<K, V> { //initialization capacity private int capacity = 10; //total entities private int size = 0; private Entity<K, V>[] entities = null; @SuppressWarnings("unchecked") public MyHashMap() { entities = new Entity[capacity]; } public void put(K key, V value) { if (key == null) { throw new RuntimeException("The key is null"); } reHash(); Entity<K, V> newEntity = new Entity<K, V>(key, value); put(newEntity, this.entities, this.capacity); } private void put(Entity<K, V> newEntity, Entity<K, V>[] entities, int capacity) { int index = newEntity.getKey().hashCode() % capacity; Entity<K, V> entity = entities[index]; Entity<K, V> firstEntity = entities[index]; if (entity == null) { entities[index] = newEntity; size++; } else { if (newEntity.getKey().equals(entity.getKey())) {//Find the same key for the first entity, if find then replace the old value to new value newEntity.setNext(entity.getNext()); newEntity.setPre(entity.getPre()); if (entity.getNext() != null) { entity.getNext().setPre(newEntity); } entities[index] = newEntity; } else if (entity.getNext() != null) { while (entity.getNext() != null) {//Find the same key for all the next entity, if find then replace the old value to new value entity = entity.getNext(); if (newEntity.getKey().equals(entity.getKey())) { newEntity.setPre(entity.getPre()); newEntity.setNext(entity.getNext()); if (entity.getNext() != null) { entity.getNext().setPre(newEntity); } entities[index] = newEntity; return; } } //Cannot find the same key, then insert the new entity at the header newEntity.setNext(firstEntity); newEntity.setPre(firstEntity.getPre()); firstEntity.setPre(newEntity); entities[index] = newEntity; size++; } else { //Cannot find the same key, then put the new entity in head newEntity.setNext(firstEntity); firstEntity.setPre(newEntity); entities[index] = newEntity; size++; } } } public V get(K key) { if (key == null) { throw new RuntimeException("The key is null"); } int index = key.hashCode() % capacity; Entity<K, V> entity = entities[index]; if (entity != null) { if (entity.getKey().equals(key)) { return entity.getValue(); } else { entity = entity.getNext(); while (entity != null) { if (entity.getKey().equals(key)) { return entity.getValue(); } entity = entity.getNext(); } } } return null; } public void remove(K key) { if (key == null) { throw new RuntimeException("The key is null"); } int index = key.hashCode() % capacity; Entity<K, V> entity = entities[index]; if (entity != null) { if (entity.getKey().equals(key)) { if (entity.getNext() != null) {//remove the first entity entity.getNext().setPre(entity.getPre()); entities[index] = entity.getNext(); entity = null; } else {//empty this index entities[index] = null; } size--; } else { entity = entity.getNext(); while (entity != null) { if (entity.getKey().equals(key)) { if (entity.getNext() != null) { entity.getPre().setNext(entity.getNext()); entity.getNext().setPre(entity.getPre()); entity = null; } else { //release the found entity entity.getPre().setNext(null); entity = null; } size--; return; } entity = entity.getNext(); } } } } public String toString() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < capacity; i++) { sb.append("index=").append(i).append("["); boolean hasEntity = false; Entity<K, V> entity = entities[i]; if (entity != null) { hasEntity = true; } while (entity != null) { sb.append("[").append(entity.getKey()).append("=").append(entity.getValue()).append("]").append(","); entity = entity.getNext(); } if (hasEntity) { sb.deleteCharAt(sb.length() - 1); } sb.append("]\n"); } return sb.toString(); } /** * Simple re-hash strategy, if the size is bigger than capacity, then do re-hash action */ private void reHash() { if (size >= capacity) { int newCapacity = capacity * 2; @SuppressWarnings("unchecked") Entity<K, V>[] newEntities = new Entity[newCapacity]; for (int i = 0; i < capacity; i++) { Entity<K, V> entity = entities[i]; while (entity != null) { put(entity, newEntities, newCapacity); entity = entity.getNext(); } } this.capacity = newCapacity; this.entities = newEntities; } } public static void main(String[] args) { MyHashMap<String, String> map = new MyHashMap<String, String>(); map.put("one", "1"); map.put("two", "2"); map.put("three", "3"); map.put("four", "4"); map.put("five", "5"); map.put("six", "6"); map.put("seven", "7"); map.put("eight", "8"); map.put("nine", "9"); map.put("ten", "10"); System.out.println(map.get("one")); System.out.println(map.get("two")); System.out.println(map.get("three")); System.out.println(map.get("four")); System.out.println(map.get("five")); System.out.println(map.get("six")); System.out.println(map.get("seven")); System.out.println(map.get("eight")); System.out.println(map.get("nine")); System.out.println(map.get("ten")); System.out.println(map.toString()); map.remove("nine"); map.remove("three"); System.out.println(map.get("one")); System.out.println(map.get("two")); System.out.println(map.get("three")); System.out.println(map.get("four")); System.out.println(map.get("five")); System.out.println(map.get("six")); System.out.println(map.get("seven")); System.out.println(map.get("eight")); System.out.println(map.get("nine")); System.out.println(map.get("ten")); System.out.println(map.toString()); } } class Entity<K, V> { private K key; private V value; private Entity<K, V> pre; private Entity<K, V> next; public Entity(K key, V value) { this.key = key; this.value = value; } public K getKey() { return key; } public void setKey(K key) { this.key = key; } public V getValue() { return value; } public void setValue(V value) { this.value = value; } public Entity<K, V> getPre() { return pre; } public void setPre(Entity<K, V> pre) { this.pre = pre; } public Entity<K, V> getNext() { return next; } public void setNext(Entity<K, V> next) { this.next = next; } }
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- 淺析java中ArrayList與Vector的區(qū)別以及HashMap與Hashtable的區(qū)別
- 深入探討JavaScript的最基本部分之執(zhí)行上下文
- 談?wù)凧avaScript中super(props)的重要性
- JavaScript常用工具方法封裝
- Java多線程實(shí)戰(zhàn)之交叉打印的兩種方法
- Java多線程實(shí)戰(zhàn)之單例模式與多線程的實(shí)例詳解
- JavaTCP上傳文本文件代碼
- Java五子棋AI實(shí)現(xiàn)代碼
- Javascript迭代、遞推、窮舉、遞歸常用算法實(shí)例講解
- ArrayList及HashMap的擴(kuò)容規(guī)則講解
相關(guān)文章
SpringBoot API接口超時(shí)時(shí)間的五種配置方式詳解
在開發(fā)API接口時(shí),配置API接口的超時(shí)時(shí)間是一項(xiàng)非常重要的任務(wù),SpringBoot中有多種方式可以配置API接口的超時(shí)時(shí)間,下面小編就為大家介紹一下吧2025-03-03java實(shí)現(xiàn)屏幕共享功能實(shí)例分析
這篇文章主要介紹了java實(shí)現(xiàn)屏幕共享功能的方法,以實(shí)例形式分析了屏幕共享功能的客戶端與服務(wù)端的詳細(xì)實(shí)現(xiàn)方法,是非常具有實(shí)用價(jià)值的技巧,需要的朋友可以參考下2014-12-12構(gòu)建springboot自動(dòng)生成mapper文件和dao接口項(xiàng)目的步驟和配置方法
這篇文章主要介紹了構(gòu)建springboot自動(dòng)生成mapper文件和dao接口項(xiàng)目的步驟和配置方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05nacos在mac上部署提示找不到或無(wú)法加載主類的解決
這篇文章主要介紹了nacos在mac上部署提示找不到或無(wú)法加載主類的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06SpringBoot開發(fā)技巧啟動(dòng)時(shí)配置校驗(yàn)實(shí)現(xiàn)示例
這篇文章主要為大家介紹了SpringBoot開發(fā)在啟動(dòng)時(shí)自動(dòng)配置校驗(yàn)的實(shí)現(xiàn)示例及原理解析,有需要的朋友可以借鑒參考下希望能夠有所幫助2021-10-10SpringBoot-Mail工具實(shí)現(xiàn)郵箱驗(yàn)證碼登錄注冊(cè)功能
現(xiàn)在許多pc程序都有著使用郵箱驗(yàn)證碼實(shí)現(xiàn)登錄注冊(cè)的功能,那么我們應(yīng)該如何完成郵箱驗(yàn)證碼功能呢,我們可以使用springboot內(nèi)置的springboot-mail再結(jié)合redis來(lái)完成這個(gè)功能,感興趣的朋友跟隨小編一起看看吧2024-07-07JavaWeb開發(fā)之Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JC
這篇文章主要介紹了JavaWeb開發(fā)之Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基礎(chǔ)框架的相關(guān)資料,需要的朋友可以參考下2016-12-12