Java 中模仿源码自定义ArrayList

Java 中模仿源码自定义ArrayList

最近看了下ArrayList的源码,抽空根据ArrayList的底层结构写了一个功能简单无泛型的自定义ArrayLsit,帮助自己更好理解ArrayList:,其实现的底层数据结构为数Object组,代码如下:

/**
 * 自己实现一个ArrayList
 *
 */
public class MyArrayList { 

  private Object[] elementData;
  private int size; 

  public int size(){
    return size;
  } 

  public boolean isEmpty(){
    return size==0;
  }
  //默认容量为10
  public MyArrayList(){
    this(10);
  }
  /**
   * 自定义容量
   * @param initialCapacity
   */
  public MyArrayList(int initialCapacity){
    if(initialCapacity<0){
      try {
        throw new Exception();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    elementData = new Object[initialCapacity];
  }
  /**
   * 添加一个元素
   * @param obj
   */
  public void add(Object obj){
    //数组扩容和数据的拷贝,重新new一个数组
    if(size==elementData.length){
      Object[] newArray = new Object[size*2+1];
      System.arraycopy(elementData, 0, newArray, 0, elementData.length); 

      elementData = newArray;
    } 

    elementData[size++]=obj;
//   size++;
  }
  /**
   * 通过索引获取元素
   * @param index
   * @return
   */
  public Object get(int index){
    rangeCheck(index); 

    return elementData[index];
  }
  /**
   * 通过索引删除元素
   * @param index
   */
  public void remove(int index){
    rangeCheck(index); 

    int numMoved = size - index - 1;
    if (numMoved > 0){
      System.arraycopy(elementData, index+1, elementData, index,
          numMoved);
    }
    elementData[--size] = null; // Let gc do its work
  }
  /**
   * 删除对应的元素(利用equal判断元素是否一致)
   * @param obj
   */
  public void remove(Object obj){
    for(int i=0;i<size;i++){
      if(get(i).equals(obj)){ //注意:底层调用的equals方法而不是==.
        remove(i);
      }
    }
  }
  /**
   * 设置索引对应的元素
   * @param index
   * @param obj
   * @return
   */
  public Object set(int index,Object obj){
    rangeCheck(index); 

    Object oldValue = elementData[index];
    elementData[index] = obj;
    return oldValue;
  }
  /**
   * 将元素插入对应的位置
   * @param index
   * @param obj
   */
  public void add(int index,Object obj){
    rangeCheck(index); 

    ensureCapacity(); //数组扩容 

    System.arraycopy(elementData, index, elementData, index + 1,
         size - index);
    elementData[index] = obj;
    size++;
  }
  /**
   * 数组扩容
   */
  private void ensureCapacity(){
    //数组扩容和数据的拷贝
        if(size==elementData.length){
          Object[] newArray = new Object[size*2+1];
          System.arraycopy(elementData, 0, newArray, 0, elementData.length);
//             for(int i=0;i<elementData.length;i++){
//               newArray[i] = elementData[i];
//             }
          elementData = newArray;
        }
  } 

  /**
   * 数组下标检查
   * @param index
   */
  private void rangeCheck(int index){
    if(index<0||index>=size){
      try {
        throw new Exception();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  } 

  public static void main(String[] args) {
    MyArrayList list = new MyArrayList(3);
    list.add("333");
    list.add("444");
    list.add("5");
    list.add("344433");
    list.add("333");
    list.add("333");
    for (int i = 0; i < list.size(); i++) {
      System.out.println(list.get(i));
    }
    System.out.println("------------------------------");
    list.remove("444");
    list.add(2, "a");
    for (int i = 0; i < list.size(); i++) {
      System.out.println(list.get(i));
    }
  } 

}

测试结果:

333

444

5

344433

333

333

------------------------------

333

5

a

344433

333

333

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Java集合删除元素ArrayList实例详解

    Java集合删除元素ArrayList实例详解 AbstractCollection集合类中有一个remove方法,该方法为了适配多种不同的集合,允许删除空的元素,看这部分代码的时候产生了疑问,为什么这里直接用it.remove()就直接删除了? public boolean remove(Object o) { Iterator<E> it = iterator(); if (o==null) { while (it.hasNext()) { if (it.next()==null) { i

  • Java中ArrayList的removeAll方法详解

    本文介绍的是关于Java中ArrayList的removeAll方法的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 在开发过程中,遇到一个情况,就是从所有骑手Id中过滤没有标签的骑手Id(直接查询没有标签的骑手不容易实现), List<Integer> allRiderIdList = new ArrayList(); // 所有的骑手,大致有23W数据 List<Integer> hasAnyTagRiderId = new ArrayList(); // 有标签

  • Java中ArrayList去除重复元素(包括字符串和自定义对象)

    1.去除重复字符串 package com.online.msym; import java.util.ArrayList; import java.util.Iterator; @SuppressWarnings({ "rawtypes", "unchecked" }) public class Demo1_ArrayList { public static void main(String[] args) { ArrayList list = new Array

  • Java中Arraylist动态扩容方法详解

    前言 本文主要给大家介绍了关于Java中Arraylist动态扩容的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. ArrayList 概述 ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长.ArrayList不是线程安全的,只能用在单线程环境下.实现了Serializable接口,因此它支持序列化,能够通过序列化传输:实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问:实现了Cloneable接口,能被克隆.

  • 对arraylist中元素进行排序实例代码

    rrayList中的元素进行排序,主要考查的是对util包中的Comparator接口和Collections类的使用. 实现Comparator接口必须实现compare方法,自己可以去看API帮助文档. 创建一个Comparator实例后,用Collections.sort(List,<E>)对List中的元素进行排序. 下面是实现代码: 以下文件必须引入util包: package com.test; import Java.util.*; Emp.java文件如下: class Emp

  • java并发容器CopyOnWriteArrayList实现原理及源码分析

    CopyOnWriteArrayList是Java并发包中提供的一个并发容器,它是个线程安全且读操作无锁的ArrayList,写操作则通过创建底层数组的新副本来实现,是一种读写分离的并发策略,我们也可以称这种容器为"写时复制器",Java并发包中类似的容器还有CopyOnWriteSet.本文会对CopyOnWriteArrayList的实现原理及源码进行分析. 实现原理 我们都知道,集合框架中的ArrayList是非线程安全的,Vector虽是线程安全的,但由于简单粗暴的锁同步机制,

  • Java 中模仿源码自定义ArrayList

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

  • java中CopyOnWriteArrayList源码解析

    目录 简介 继承体系 源码解析 属性 构造方法 add(Ee)方法 add(intindex,Eelement)方法 addIfAbsent(Ee)方法 get(intindex) remove(intindex)方法 size()方法 提问 总结 简介 CopyOnWriteArrayList是ArrayList的线程安全版本,内部也是通过数组实现,每次对数组的修改都完全拷贝一份新的数组来修改,修改完了再替换掉老数组,这样保证了只阻塞写操作,不阻塞读操作,实现读写分离. 继承体系 public

  • java 中Buffer源码的分析

    java 中Buffer源码的分析 Buffer Buffer的类图如下: 除了Boolean,其他基本数据类型都有对应的Buffer,但是只有ByteBuffer才能和Channel交互.只有ByteBuffer才能产生Direct的buffer,其他数据类型的Buffer只能产生Heap类型的Buffer.ByteBuffer可以产生其他数据类型的视图Buffer,如果ByteBuffer本身是Direct的,则产生的各视图Buffer也是Direct的. Direct和Heap类型Buff

  • Java中LinkedHashMap源码解析

    概述: LinkedHashMap实现Map继承HashMap,基于Map的哈希表和链该列表实现,具有可预知的迭代顺序. LinedHashMap维护着一个运行于所有条目的双重链表结构,该链表定义了迭代顺序,可以是插入或者访问顺序. LintHashMap的节点对象继承HashMap的节点对象,并增加了前后指针 before after: /** * LinkedHashMap节点对象 */ static class Entry<K,V> extends HashMap.Node<K,V

  • Java集合框架源码分析之LinkedHashMap详解

    LinkedHashMap简介 LinkedHashMap是HashMap的子类,与HashMap有着同样的存储结构,但它加入了一个双向链表的头结点,将所有put到LinkedHashmap的节点一一串成了一个双向循环链表,因此它保留了节点插入的顺序,可以使节点的输出顺序与输入顺序相同. LinkedHashMap可以用来实现LRU算法(这会在下面的源码中进行分析). LinkedHashMap同样是非线程安全的,只在单线程环境下使用. LinkedHashMap源码剖析 LinkedHashM

  • Java struts2请求源码分析案例详解

    Struts2是Struts社区和WebWork社区的共同成果,我们甚至可以说,Struts2是WebWork的升级版,他采用的正是WebWork的核心,所以,Struts2并不是一个不成熟的产品,相反,构建在WebWork基础之上的Struts2是一个运行稳定.性能优异.设计成熟的WEB框架. 我这里的struts2源码是从官网下载的一个最新的struts-2.3.15.1-src.zip,将其解压即可.里面的目录页文件非常的多,我们只需要定位到struts-2.3.15.1\src\core

  • Java OkHttp框架源码深入解析

    目录 1.OkHttp发起网络请求 可以通过OkHttpClient发起一个网络请求 通过Retrofit发起一个OkHttp请求 2.OkHttp的连接器 1.OkHttp发起网络请求 可以通过OkHttpClient发起一个网络请求 //创建一个Client,相当于打开一个浏览器 OkHttpClient okHttpClient = new OkHttpClient.Builder().build(); //创建一个请求. Request request = new Request.Bui

  • Java从JDK源码角度对Object进行实例分析

    Object是所有类的父类,也就是说java中所有的类都是直接或者间接继承自Object类.比如你随便创建一个classA,虽然没有明说,但默认是extendsObject的. 后面的三个点"..."表示可以接受若干不确定数量的参数.老的写法是Objectargs[]这样,但新版本的java中推荐使用...来表示.例如 publicvoidgetSomething(String...strings)(){} object是java中所有类的父类,也就是说所有的类,不管是自己创建的类还是

  • 通过java.util.TreeMap源码加强红黑树的理解

    在此之前,我们已经为大家整理了很多关于经典问题红黑树的思路和解决办法.本篇文章,是通过分析java.util.TreeMap源码,让大家通过实例来对红黑树这个问题有更加深入的理解. 本篇将结合JDK1.6的TreeMap源码,来一起探索红-黑树的奥秘.红黑树是解决二叉搜索树的非平衡问题. 当插入(或者删除)一个新节点时,为了使树保持平衡,必须遵循一定的规则,这个规则就是红-黑规则:  1) 每个节点不是红色的就是黑色的  2) 根总是黑色的  3) 如果节点是红色的,则它的子节点必须是黑色的(反

  • Java中invokedynamic字节码指令问题

    1. 方法引用和invokedynamic invokedynamic是jvm指令集里面最复杂的一条.本文将从高观点的角度下分析invokedynamic指令是如何实现方法引用(Method reference)的. 具体言之,有这样一个方法引用: interface Encode { void encode(Derive person); } class Base { public void encrypt() { System.out.println("Base::speak");

随机推荐