Java泛型模拟scala实现自定义ArrayList方式

 更新时间:2021年10月11日 08:40:36   作者:遥遥晚风点点  
这篇文章主要介绍了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中序列化与反序列化的特性解读

    Java中序列化与反序列化的特性解读

    这篇文章主要介绍了Java中序列化与反序列化的特性解读,当我们需要将内存中的对象持久化到磁盘,数据库中时, 当我们需要与浏览器进行交互时,当我们需要实现 RPC 时, 这个时候就需要序列化和反序列化了,需要的朋友可以参考下
    2023-08-08
  • Redis 订阅发布_Jedis实现方法

    Redis 订阅发布_Jedis实现方法

    下面小编就为大家带来一篇Redis 订阅发布_Jedis实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • Spring Boot实战教程之自动配置详解

    Spring Boot实战教程之自动配置详解

    Spring Boot的自动配置给开发者带来了很大的便利,当开发人员在pom文件中添加starter依赖后,maven或者gradle会自动下载很多jar包到classpath中。下面这篇文章主要给大家介绍了关于Spring Boot自动配置的相关资料,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-07-07
  • Spring Boot如何接入Security权限认证服务

    Spring Boot如何接入Security权限认证服务

    Spring Security 是一个高度可定制的身份验证和访问控制的框架,提供了完善的认证机制和方法级的授权功能,本文通过案例将Spring Security整合到SpringBoot中,要实现的功能就是在认证服务器上登录,然后获取Token,再访问资源服务器中的资源,感兴趣的朋友一起看看吧
    2024-07-07
  • SpringBoot整合Druid实现数据库连接池和监控

    SpringBoot整合Druid实现数据库连接池和监控

    Druid是Java语言中使用的比较多的数据库连接池。Druid还提供了强大的监控和扩展功能。面将介绍SpringBoot整合Druid实现数据库连接池和监控功能,感兴趣的可以了解一下
    2021-08-08
  • mybatis generator只能生成insert和selectAll的操作

    mybatis generator只能生成insert和selectAll的操作

    这篇文章主要介绍了mybatis generator只能生成insert和selectAll的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • 聊聊Java BigInteger里面的mod和remainder的区别

    聊聊Java BigInteger里面的mod和remainder的区别

    这篇文章主要介绍了聊聊Java BigInteger里面的mod和remainder的区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08
  • 快速使用IDEA图形化界面连接Phoenix的方法

    快速使用IDEA图形化界面连接Phoenix的方法

    最近很多朋友跟小编留言如何使用IDEA图形化界面连接Phoenix,在这小编就不一一回复大家了,今天抽空给大家整理一篇教程关于idea 图形化界面连接Phoenix的相关知识,需要的朋友快来学习下吧
    2021-05-05
  • Spring Boot 基于 SCRAM 认证集成 Kafka 的过程详解

    Spring Boot 基于 SCRAM 认证集成 Kafka 的过程详解

    在本篇文章中,我们将探讨如何在 Spring Boot 应用中集成 Kafka 并使用 SCRAM 认证机制进行安全连接,并实现动态创建账号、ACL 权限、Topic,以及生产者和消费者等操作,感兴趣的朋友跟随小编一起看看吧
    2024-08-08
  • Java编写实现多人聊天室

    Java编写实现多人聊天室

    这篇文章主要为大家详细介绍了Java编写实现多人聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09

最新评论