Java泛型模擬scala實(shí)現(xiàn)自定義ArrayList方式
泛型模擬scala實(shí)現(xiàn)自定義ArrayList
泛型就是將類型由原來的具體的類型參數(shù)化,類似于方法中的變量參數(shù),此時(shí)類型也定義成參數(shù)形式(可以稱之為類型形參),
然后在使用/調(diào)用時(shí)傳入具體的類型
操作的數(shù)據(jù)類型被指定為一個(gè)參數(shù),這種參數(shù)類型可以用在類、接口和方法中,分別被稱為泛型類、泛型接口、泛型方法。
以下實(shí)例通過泛型,靈活的實(shí)現(xiàn)了類似scala中集合的map,reduce方法,并可以鏈?zhǔn)骄幊?/p>
Function1:一個(gè)入?yún)⒌姆盒徒涌冢鏼ap(),filter()
//泛型接口 public interface Function1<T, R> { R call(T t); }
Function2:兩個(gè)入?yún)⒌姆盒徒涌?,例如reduce()
//泛型接口 public interface Function2<E> { E call(E elem,E sum); }
MyList:自定義List
import java.util.ArrayList; //泛型類 public class MyList<E> extends ArrayList<E> { //泛型方法 (只有在public修飾符和返回值之間用了泛型的才是泛型方法,指定后,該方法內(nèi)可以使用該泛型) public <R> MyList<R> map(Function1<E, R> fun){ MyList<R> myList = new MyList<>(); for (E e : this) { R res = fun.call(e); myList.add(res); } return myList; } //這個(gè)不是泛型方法,泛型在引用時(shí)指定,可以是泛型類中已經(jīng)定義的,也可以是具體的類 public MyList<E> filter(Function1<E,Boolean> fun){ MyList<E> myList = new MyList<>(); for(E elem : this){ Boolean flag = fun.call(elem); if(flag){ myList.add(elem); } } return myList; } //這個(gè)也不是泛型方法 public E reduce(Function2<E> fun){ E sum = null; boolean isFirst = true; for (E elem : this) { if(isFirst){ sum = elem; isFirst = false; }else { sum = fun.call(elem,sum); } } return sum; } }
測試:
public class MyTest { public static void main(String[] args) { MyList<String> myList = new MyList<>(); myList.add("aaaa"); myList.add("bbbb"); myList.add("cccc"); myList.add("accc"); String res = myList.filter(x -> x.contains("a")).map(x -> x.toUpperCase()).reduce((x, y) -> x + y); System.out.println(res); } }
輸出:
自定義實(shí)現(xiàn)ArrayList代碼
"雙十一讓你明白,有些東西,打半折你也買不起;就像你喜歡的人,眼光降低一半,還是看不上你“。所以,在JDK1.8中,ArrayList底層是怎么實(shí)現(xiàn)的呢?(看源碼能理解就行)
/** * 自定義實(shí)現(xiàn)ArrayList */ public class TextArrayList<E> { private Object[] elementData; private int size; private static final int DEFALT_CAPACITY = 10; /** * 無參構(gòu)造,默認(rèn)數(shù)組大小為10 */ public TextArrayList() { elementData = new Object[DEFALT_CAPACITY]; } /** * 有參構(gòu)造,數(shù)組大小為傳入的值 */ public TextArrayList(int capacity) { if (capacity < 0) { throw new RuntimeException("容器容量不能為負(fù)數(shù)"); } else if (capacity == 0) { elementData = new Object[DEFALT_CAPACITY]; } else { elementData = new Object[capacity]; } } /** * 給數(shù)組中添加元素 * * @param element */ public void add(E element) { //數(shù)組擴(kuò)容 if (size == elementData.length) { Object[] newArray = new Object[elementData.length + (elementData.length >> 1)]; System.arraycopy(elementData, 0, newArray, 0, elementData.length); elementData = newArray; } elementData[size++] = element; } /** * 刪除元素 * 挨個(gè)比較所有元素,獲得第一個(gè)比較結(jié)果為True的,返回 * * @return */ public void remove(E element) { for (int i = 0; i < size; i++) { if (element.equals(get(i))) { //比較操作用到equals方法 System.arraycopy(elementData, i + 1, elementData, i, elementData.length - i - 1); elementData[size - 1] = null; size--; } } } /** * 刪除索引 * * @return */ public void remove(int index) { int numMoved = elementData.length - index - 1; if (numMoved > 0) { System.arraycopy(elementData, index + 1, elementData, index, numMoved); } elementData[size - 1] = null; size--; } /** * 判空 * * @return */ public boolean isEmpty() { return size == 0 ? true : false; } @Override public String toString() { StringBuilder stringBuilder = new StringBuilder(); //[a,b,c] stringBuilder.append("["); for (int i = 0; i < size; i++) { stringBuilder.append(elementData[i] + ","); } stringBuilder.setCharAt(stringBuilder.length() - 1, ']'); return stringBuilder.toString(); } /** * 增加get方法 * * @param index */ public E get(int index) { checkRange(index); return (E) elementData[index]; } /** * 增加set方法 * * @param index */ public void set(E element, int index) { checkRange(index); elementData[index] = element; } //判斷索引合法性 public void checkRange(int index) { if (index < 0 || index > size - 1) { throw new RuntimeException("索引不合法:" + index); } } public static void main(String[] args) { TextArrayList t1 = new TextArrayList(20); // t1.add("aa"); // t1.add("bb"); for (int i = 0; i < 40; i++) { t1.add("wang" + i); } t1.set("sss", 10); System.out.println(t1); System.out.println(t1.get(39)); t1.remove(3); t1.remove("wang5"); System.out.println(t1); System.out.println(t1.size); System.out.println(t1.isEmpty()); } }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springmvc使用@notNull注解驗(yàn)證請(qǐng)求參數(shù)方式
這篇文章主要介紹了springmvc使用@notNull注解驗(yàn)證請(qǐng)求參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教<BR>2024-01-01spring整合redis緩存并以注解(@Cacheable、@CachePut、@CacheEvict)形式使用
本篇文章主要介紹了spring整合redis緩存并以注解(@Cacheable、@CachePut、@CacheEvict)形式使用,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-04-04Java OpenSSL生成的RSA公私鑰進(jìn)行數(shù)據(jù)加解密詳細(xì)介紹
這篇文章主要介紹了Java OpenSSL生成的RSA公私鑰進(jìn)行數(shù)據(jù)加解密詳細(xì)介紹的相關(guān)資料,這里提供實(shí)例代碼及說明具體如何實(shí)現(xiàn),需要的朋友可以參考下2016-12-12springboot 同時(shí)啟用http/https的配置方法
本文給大家分享springboot 同時(shí)啟用http/https的配置方法,通過修改配置文件、增加java配置的方法來實(shí)現(xiàn)此操作,具體內(nèi)容詳情跟隨小編通過本文學(xué)習(xí)下吧2021-05-05java通過jacob實(shí)現(xiàn)office在線預(yù)覽功能
這篇文章主要為大家詳細(xì)介紹了java通過jacob實(shí)現(xiàn)office在線預(yù)覽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-08-08