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

目录
  • 泛型模拟scala实现自定义ArrayList
  • 自定义实现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());
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Scala中Array和List的区别说明

    目录 Scala Array和List的区别 Scala快排List和Array数组效率实测 Scala Array和List的区别 Difference between Array and List in scala Q:什么时候用Array(Buffer)和List(Buffer)? A:Scala中的List是不可变的递归数据(immutable recursive data),是Scala中的一种基础结构,你应该多用List而不是Array(Array实际上是mutable,不可变(im

  • Scala解析Json字符串的实例详解

    Scala解析Json字符串的实例详解 1. 添加相应依赖 Json解析工具使用的 json-smart,曾经对比过Java的fastjson.gson.Scala的json4s.lift-json.其中 json-smart 解析速度是最快的. <dependency> <groupId>net.minidev</groupId> <artifactId>json-smart</artifactId> <version>2.3<

  • Scala入门之List使用详解

    Scala中使用List Scala是函数式风格与面向对象共存的编程语言,方法不应该有副作用是函数风格编程的一个重要的理念.方法唯一的效果应该是计算并返回值,用这种方式工作的好处就是方法之间很少纠缠在一起,因此就更加可靠和可重用.另一个好处(静态类型语言)是传入传出方法的所有东西都被类型检查器检查,因此逻辑错误会更有可能把自己表现为类型错误.把这个函数式编程的哲学应用到对象世界里以为着使对象不可变. 前面一章介绍的Array数组是一个所有对象都共享相同类型的可变序列.比方说Array[Strin

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

    目录 泛型模拟scala实现自定义ArrayList 自定义实现ArrayList代码 泛型模拟scala实现自定义ArrayList 泛型就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参), 然后在使用/调用时传入具体的类型 操作的数据类型被指定为一个参数,这种参数类型可以用在类.接口和方法中,分别被称为泛型类.泛型接口.泛型方法. 以下实例通过泛型,灵活的实现了类似scala中集合的map,reduce方法,并可以链式编程 Functi

  • Java 中模仿源码自定义ArrayList

    Java 中模仿源码自定义ArrayList 最近看了下ArrayList的源码,抽空根据ArrayList的底层结构写了一个功能简单无泛型的自定义ArrayLsit,帮助自己更好理解ArrayList:,其实现的底层数据结构为数Object组,代码如下: /** * 自己实现一个ArrayList * */ public class MyArrayList { private Object[] elementData; private int size; public int size(){

  • Java泛型在集合使用与自定义及继承上的体现和通配符的使用

    泛型的概念 集合容器类在设计阶段/声明阶段不能确定这个容器实际存的是什么类型的对象,所以在JDK1.5之前只能把元素类型设计为Object,JDK1.5之后使用泛型来解决.因为这个时候除了元素的类型不确定,其他的部分是确定的,例如关于这个元素如何保存,如何管理等是确定的,因此把元素的类型设计成一个参数,这个类型参数叫做泛型.Collection<E>,ArrayList<E> 中<E>就是类型参数,即泛型. 所谓泛型,就是允许在定义类.接口时通过一个标识表示类中某个属性

  • Java和Scala集合间的相互转换方式

    目录 Java和Scala集合间的相互转换 scala与java互转 Java与Scala的集合对比 一.Java集合 1.Collection=>Set接口 2.Collection=>List接口 3.Map接口 二.Scala集合 1.Seq 2.Set 3.Map Java和Scala集合间的相互转换 在scala中,调用一个java的方法,通常需要传递相应的参数.下面是scala与java互转换对应表 Iterator <=> java.util.Iterator Ite

  • java通过模拟post方式提交表单实现图片上传功能实例

    本文实例讲述了java通过模拟post方式提交表单实现图片上传功能.分享给大家供大家参考,具体如下: 模拟表单html如下: <form action="up_result.jsp" method="post" enctype="multipart/form-data" name="form1" id="form1"> <label> <input type="tex

  • java模拟发送form-data的请求方式

    我就废话不多说了,大家还是直接看代码吧! package com.silot.test; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntity; import org.apa

  • Java实现自定义ArrayList类的示例代码

    目录 一.总体实现思路 二.add方法 三.size方法 四.isEmpty方法 五.构造方法 六.ArrayList整体代码 七.Test测试类 之前有接触过Collection中的ArrayList类,类中提供了多种可以操作的方法,但是为什么还需要自定义ArrayList类呢?主要是为了学习其中编写程序时的逻辑思维.,今天将简单的介绍ArrayList里面的add方法.size方法.isEmpty方法. 一.总体实现思路 在自定义ArrayList类时需要提前思考多个方面的内容 1.该Arr

  • 详谈Java泛型中T和问号(通配符)的区别

    类型本来有:简单类型和复杂类型,引入泛型后把复杂类型分的更细了. 概述 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.这种参数类型可以用在类.接口和方法的创建中,分别称为泛型类.泛型接口.泛型方法. Java语言引入泛型的好处是安全简单. 在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的"任意化","任意化"带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对

  • 详解Java泛型及其应用

    引出泛型 我们通过如下的示例,引出为什么泛型的概念. public class Test { public static void main(String[] args) { List list = new ArrayList(); list.add("abc"); list.add(2); for (int i = 0; i < list.size(); i++) { String name = (String) list.get(i); // error System.out

  • Java泛型最全知识总结

    一.泛型简介 1.1 泛型的概念 所谓泛型,就是允许在定义类.接口时通过一个标识表示类中某个属性的类型或者是某个方法的返 回值及参数类型.这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量. 创建对象时确定(即传入实际的类型参数,也称为类型实参). 从JDK 5.0以后,Java引入了"参数化类型(Parameterized type)"的概念,允许我们在创建集合时再指定集合元素的类型,正如:List,这表明该List只能保存字符串类型的对象. JDK 5.0改写了集

随机推荐