3.4 MyArrayList 类的实现

这节提供一个便于使用的 MyArrayList 泛型类的实现,这里不检测可能使得迭代器无效的结构上的修改,也不检测非法的迭代器 remove 方法。

  1. MyArrayList 将保持基础数组,数组的容量,以及存储在MyArrayList 中的当前项数。
  2. MyArrayList 将提供一种机制以改变基础数组的容量。通过获得一个新数组,将老数组拷贝到新数组中来改变数组的容量,允许虚拟机回收老数组。
  3. MyArrayList 将提供 get 和 set 的实现。
  4. MyArrayList 将提供基本的例程,如 size 、isEmpty 和 clear,它们是典型的单行程序;还提供 remove,以及两种不同版本的 add。如果数组大小和容量相同,那么这两个 add 例程将增加容量。
  5. MyArrayList 将提供一个实现 Iterator 接口的类。这个类将储存迭代序列中的下一项的下标,并提供 next、hasNext 和 remove 等方法的实现。MyArrayList 的迭代器方法直接返回实现 Iterator 接口的该类的新构造的实例。
public class MyArrayList<E> implements Iterable<E> {

    public static final int DEFAULT_CAPACITY = 10;//默认数组长度

    private int theSize;

    private E[] theItems;

    public MyArrayList() {
doClear();
} public void clear() {
doClear();
} private void doClear() {
theSize = 0;
ensureCapacity(DEFAULT_CAPACITY);
} public int size() {
return theSize;
} public boolean isEmpty() {
return theSize == 0;
} public void trimToSize() {//将当前数组复制到一个大小刚好合适的数组中
ensureCapacity(theSize);
} public E get(int idx) {
if (idx < 0 || idx >= theSize) {
throw new ArrayIndexOutOfBoundsException();
}
return theItems[idx];
} public E set(int idx, E newVal) {
if (idx < 0 || idx >= theSize) {
throw new ArrayIndexOutOfBoundsException();
}
E old = theItems[idx];
theItems[idx] = newVal;
return old;
} public void ensureCapacity(int newCapacity) {
if (newCapacity < theSize) {
return;
}
E[] old = theItems;
theItems = (E[]) new Object[newCapacity];
for (int i = 0; i < theSize; i++) {
theItems[i] = old[i];
}
} public boolean add(E x) {
add(theSize, x);
return true;
} public void add(int idx, E x) {
if (theItems.length == theSize) {
ensureCapacity(theSize * 2 + 1);//+1应对大小为0时的情况
}
for (int i = theSize; i > idx; i--) {
theItems[i] = theItems[i - 1];
}
theItems[idx] = x;
theSize++;
} public E remove(int idx) {
E removedItem = theItems[idx];
for (int i = idx; i < theSize; i++) {
theItems[i] = theItems[i + 1];
}
theSize--;
return removedItem;
} public Iterator<E> iterator() {
return new ArrayListIterator();
} private class ArrayListIterator implements Iterator<E> { private int current = 0; public boolean hasNext() {
return current < size();
} public E next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
return theItems[current++];
} public void remove() {
MyArrayList.this.remove(--current);
}
}
}

ArrayListIterator 是 MyArrayList 的内部类,可以直接访问 MyArrayList 的 private 实例

3.4 MyArrayList 类的实现的更多相关文章

  1. 实现MyArrayList类深入理解ArrayList

    ArrayList简介 ArrayList是一个动态数组,Array的复杂版本,它提供了动态的增加和减少元素,实现了ICollection和IList接口,灵活的设置数组的大小等好处. MyArray ...

  2. 实现一个自定义的ArrayList类,实现将原List中的每个数据都乘以10

    1.首先自定义一个Operate接口,如下所示: public interface Operate { public Integer caozuo(Integer i); } 2.实现自定义的Arra ...

  3. Java类的继承与多态特性-入门笔记

    相信对于继承和多态的概念性我就不在怎么解释啦!不管你是.Net还是Java面向对象编程都是比不缺少一堂课~~Net如此Java亦也有同样的思想成分包含其中. 继承,多态,封装是Java面向对象的3大特 ...

  4. 转载yield关键字理解

    实现IEnumerable接口及理解yield关键字   [摘要]本文介绍实现IEnumerable接口及理解yield关键字,并讨论IEnumerable接口如何使得foreach语句可以使用. 本 ...

  5. 容器_JDK源码分析_自己简单实现ArrayList容器

    这几天仔细研究下关于ArrayList容器的jdk源码,感觉收获颇多,以前自己只知道用它,但它里面具体是怎样实现的就完全不清楚了.于是自己尝试模拟写下java的ArrayList容器,简单了实现的Ar ...

  6. [原译]实现IEnumerable接口&理解yield关键字

    原文:[原译]实现IEnumerable接口&理解yield关键字 著作权声明:本文由http://leaver.me 翻译,欢迎转载分享.请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢 ...

  7. Java不可不知的泛型使用

    前面的文章: 详解Java的对象创建 一文打尽Java继承的相关问题 一文打尽Java抽象类和接口的相关问题 本文介绍了Java的泛型的基本使用. 1. 为什么使用泛型 看下面一个例子: 为了说明问题 ...

  8. 模仿.NET框架ArrayList写一个自己的动态数组类MyArrayList,揭示foreach实现原理

    通过.NET反编译工具可以查看到ArrayList内部的代码,发现ArrayList并非由链表实现,而是由一个不断扩容的数组对象组成. 下面模仿ArrayList写一个自己的MyArrayList. ...

  9. .net学习之集合、foreach原理、Hashtable、Path类、File类、Directory类、文件流FileStream类、压缩流GZipStream、拷贝大文件、序列化和反序列化

    1.集合(1)ArrayList内部存储数据的是一个object数组,创建这个类的对象的时候,这个对象里的数组的长度为0(2)调用Add方法加元素的时候,如果第一次增加元神,就会将数组的长度变为4往里 ...

随机推荐

  1. 【题解】CF1324F

    Question 题目大意:每个点不是黑点就是白点,求以每一个点为根时,选择出一个联通块,使得白点数与黑点数之差最大(白减黑). \(Solution\) 考虑先跑一遍\(dp\). 可以写出一个比较 ...

  2. Centos 6.9 安装 php5.6

    1.检查当前安装的PHP包 yum list installed | grep php 如果有安装的PHP包,先删除他们, 如: yum remove php.x86_64 php-cli.x86_6 ...

  3. 设置 eclipse C++ 版本

    gcc 版本 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) 默认是使用 C++ 98 版本进行编译 设置 eclipse 中 C++ 的版本: Project  -& ...

  4. shell-变量的字串应用技术

    1. 变量子串的常用操作 常用操作如下表: 依次举例说明: 定义aa变量,内容为"I am scajy" [root@1-241 script]# aa="I am sc ...

  5. Anaconda安装和使用 akshare获取股票数据

    介绍 Anaconda是开源的Python包管理器.既是Python各种库的大礼包集合,特别是数据分析和科学计算方面的库都预装了,也是一个能创建虚拟机环境的工具. 我为什么安装 我安装它的原因不是科学 ...

  6. IP协议那些事

    IP协议作为通信子网的最高层.提供无连接的数据报传输机制. IP协议的作用 寻址和路由 传递服务:提供不可靠,无连接的服务. 为什么说IP协议不可靠.无连接 不可靠:是指不能保证IP数据包能成成功到达 ...

  7. async-await和Promise的关系

    关于异步处理,ES5的回调使我们陷入地狱,ES6的Promise使我们脱离魔障,终于.ES7的async-await带我们走向光明.今天就来学习一下 async-await. 经常会看到有了 asyn ...

  8. 使用 volatile 关键字保证变量可见性和禁止指令重排序

    volatile 概述 volatile 是 Java 提供的一种轻量级的同步机制.相比于传统的 synchronize,虽然 volatile 能实现的同步性要差一些,但开销更低,因为它不会引起频繁 ...

  9. zookeeper 集群搭建 转

    通过 VMware ,我们安装了三台虚拟机,用来搭建 zookeeper 集群,虚拟机网络地址如下: hostname                      ipaddress           ...

  10. ps 批量kill进程

    Linux下批量kill掉进程   ps -ef|grep java|grep -v grep|cut -c 9-15|xargs kill -9 管道符"|"用来隔开两个命令,管 ...