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)文章
Redis 訂閱發(fā)布_Jedis實(shí)現(xiàn)方法
下面小編就為大家?guī)硪黄猂edis 訂閱發(fā)布_Jedis實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06
Spring Boot實(shí)戰(zhàn)教程之自動(dòng)配置詳解
Spring Boot的自動(dòng)配置給開發(fā)者帶來了很大的便利,當(dāng)開發(fā)人員在pom文件中添加starter依賴后,maven或者gradle會(huì)自動(dòng)下載很多jar包到classpath中。下面這篇文章主要給大家介紹了關(guān)于Spring Boot自動(dòng)配置的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。2017-07-07
Spring?Boot如何接入Security權(quán)限認(rèn)證服務(wù)
Spring Security?是一個(gè)高度可定制的身份驗(yàn)證和訪問控制的框架,提供了完善的認(rèn)證機(jī)制和方法級的授權(quán)功能,本文通過案例將Spring Security整合到SpringBoot中,要實(shí)現(xiàn)的功能就是在認(rèn)證服務(wù)器上登錄,然后獲取Token,再訪問資源服務(wù)器中的資源,感興趣的朋友一起看看吧2024-07-07
SpringBoot整合Druid實(shí)現(xiàn)數(shù)據(jù)庫連接池和監(jiān)控
Druid是Java語言中使用的比較多的數(shù)據(jù)庫連接池。Druid還提供了強(qiáng)大的監(jiān)控和擴(kuò)展功能。面將介紹SpringBoot整合Druid實(shí)現(xiàn)數(shù)據(jù)庫連接池和監(jiān)控功能,感興趣的可以了解一下2021-08-08
mybatis generator只能生成insert和selectAll的操作
這篇文章主要介紹了mybatis generator只能生成insert和selectAll的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09
聊聊Java BigInteger里面的mod和remainder的區(qū)別
這篇文章主要介紹了聊聊Java BigInteger里面的mod和remainder的區(qū)別,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Spring?Boot?基于?SCRAM?認(rèn)證集成?Kafka?的過程詳解
在本篇文章中,我們將探討如何在?Spring?Boot?應(yīng)用中集成?Kafka?并使用?SCRAM?認(rèn)證機(jī)制進(jìn)行安全連接,并實(shí)現(xiàn)動(dòng)態(tài)創(chuàng)建賬號、ACL?權(quán)限、Topic,以及生產(chǎn)者和消費(fèi)者等操作,感興趣的朋友跟隨小編一起看看吧2024-08-08

