Java泛型模拟scala实现自定义ArrayList方式
泛型模拟scala实现自定义ArrayList
泛型就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),
然后在使用/调用时传入具体的类型
操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
以下实例通过泛型,灵活的实现了类似scala中集合的map,reduce方法,并可以链式编程
Function1:一个入参的泛型接口,例如map(),filter()
//泛型接口 public interface Function1<T, R> { R call(T t); }
Function2:两个入参的泛型接口,例如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修饰符和返回值之间用了泛型的才是泛型方法,指定后,该方法内可以使用该泛型) 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; } //这个不是泛型方法,泛型在引用时指定,可以是泛型类中已经定义的,也可以是具体的类 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; } //这个也不是泛型方法 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); } }
输出:
自定义实现ArrayList代码
"双十一让你明白,有些东西,打半折你也买不起;就像你喜欢的人,眼光降低一半,还是看不上你“。所以,在JDK1.8中,ArrayList底层是怎么实现的呢?(看源码能理解就行)
/** * 自定义实现ArrayList */ public class TextArrayList<E> { private Object[] elementData; private int size; private static final int DEFALT_CAPACITY = 10; /** * 无参构造,默认数组大小为10 */ public TextArrayList() { elementData = new Object[DEFALT_CAPACITY]; } /** * 有参构造,数组大小为传入的值 */ public TextArrayList(int capacity) { if (capacity < 0) { throw new RuntimeException("容器容量不能为负数"); } else if (capacity == 0) { elementData = new Object[DEFALT_CAPACITY]; } else { elementData = new Object[capacity]; } } /** * 给数组中添加元素 * * @param element */ public void add(E element) { //数组扩容 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; } /** * 删除元素 * 挨个比较所有元素,获得第一个比较结果为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()); } }
以上为个人经验,希望能给大家一个参考,也希望大家多多支持猪先飞。
相关文章
- 这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
java 运行报错has been compiled by a more recent version of the Java Runtime
java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01- 这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
- 这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
- 说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
- 这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
- 这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
- 这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
java 画pdf用itext调整表格宽度、自定义各个列宽的方法
这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
Java使用ScriptEngine动态执行代码(附Java几种动态执行代码比较)
这篇文章主要介绍了Java使用ScriptEngine动态执行代码,并且分享Java几种动态执行代码比较,需要的朋友可以参考下...2021-04-15- 这篇文章主要介绍了Java开发实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-03
- 这篇文章主要介绍了C#泛型的类型参数约束的相关资料,文中讲解非常细致,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2020-07-31
Java 8 Stream 的终极技巧——Collectors 功能与操作方法详解
这篇文章主要介绍了Java 8 Stream Collectors 功能与操作方法,结合实例形式详细分析了Java 8 Stream Collectors 功能、操作方法及相关注意事项,需要的朋友可以参考下...2020-05-20- 这篇文章主要介绍了Java List集合返回值去掉中括号('[ ]')的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-29
- 这篇文章主要介绍了C#泛型类型知识,文中代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-06-25
Java中lombok的@Builder注解的解析与简单使用详解
这篇文章主要介绍了Java中lombok的@Builder注解的解析与简单使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-06- 下面小编就为大家带来一篇java中String类型变量的赋值问题介绍。小编觉得挺不错的。现在分享给大家,给大家一个参考。...2016-03-28