数组与集合的转换

  • 集合 --> 数组
    Collection: T[] toArray(T[] arr);
  • 数组 --> 集合
    static List asList(T… a) 视图方法
    但是不能增加和删除元素

jdk5特性:
a.泛型
b.自动装箱和自动拆箱
c.静态导入
d.foreach
e.可变长参数

public static void main(String[] args) {Integer[] arr = {1, 2, 3, 4, 5};List<Integer> list = Arrays.asList(arr); // 视图方法System.out.println(list);添加元素:不可list.add(6); // UnsupportedOperationException删除元素:不可list.remove(0); // UnsupportedOperationException修改元素:可list.set(0, 100);System.out.println(list);System.out.println(Arrays.toString(arr));}

数据结构

  • 数据结构是相互之间存在一种或多种特定关系的数据元素的集合。
  • 公式:数据结构=数据+结构
  • 数据:用类型表示结构:在任何问题中,数据元素都不是孤立存在的,它们之间都存在着某种关系,这种数据元素相互之间的关系称为结构。
  • 元素之间,通常有以下四种基本结构:
    a.集合:结构中的数据元素之间除了同属于一个集合的关系之外,别无其他关系。这里的集合和数学中集合的概念是一致的。
    b.线性结构:结构中的数据元素之间存在一个对一个的关系。
    c.树形结构图:结构中的数据元素之间存在一个对多个的关系。
    d.网状结构:结构中的数据元素之间,存在多个对多个的关系。

逻辑结构&物理结构

  • 前面分类中定义的关系,描述的是数据元素间的逻辑关系,因此又称为逻辑结构。
  • 但是仅仅知道数据元素间的逻辑关系是不够的,因为我们得实现自己的数据结构。 因此,我们得关注数据结构在计算机底层是如何表示的?
  • 数据结构在计算机中的表示,称为数据的物理结构,又称为存储结构或者映像。

结构的表示可分为两种:顺序存储结构 (顺序映像) 和 链式存储结构 (非顺序映像)。

  • 顺序映像:借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系。(数组)
  • 非顺序映像:借助指示元素存储地址的”指针”,来表示数据元素的逻辑关系。(链表)

线性表:

  • 顺序映像 (ArrayList)
  • 非顺序映像 (LinkedList)

MyArrayList

为什么在迭代器遍历的时候,用集合的API删除倒数第二个元素不会报异常?


import com.cskaoyan.exception.ArrayListOverflowException;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.NoSuchElementException;public class MyArrayList<E> implements MyList<E> {private static final int DEFAULT_CAPACITY = 10;private static final int MAX_CAPACITY = Integer.MAX_VALUE - 8;// 属性private Object[] elements;private int size;private int modCount;//集合结构被修改的次数// 构造方法public MyArrayList() {elements = new Object[DEFAULT_CAPACITY];}public MyArrayList(int initialCapacity) {// 及早失败原则if (initialCapacity <= 0 || initialCapacity > MAX_CAPACITY) {throw new IllegalArgumentException("initialCapacity=" + initialCapacity);}elements = new Object[initialCapacity];}/*** 在线性表的末尾添加元素** @param e 待添加的元素* @return 如果添加成功返回true*/@Overridepublic boolean add(E e) {add(size, e);return true;}/*** 在线性表中指定索引位置添加元素** @param index 指定索引位置* @param e     待添加的元素*/@Overridepublic void add(int index, E e) {checkIndexForAdd(index);// 判断是否需要扩容if (size == elements.length) {int minCapacity = size + 1;// 计算新数组的大小int newCapacity = calculateCapacity(minCapacity);// 扩容grow(newCapacity);}// 添加元素for (int i = size; i > index; i--) {elements[i] = elements[i - 1];}elements[index] = e;size++;modCount++;}private void grow(int newCapacity) {Object[] newArr = new Object[newCapacity];for (int i = 0; i < size; i++) {newArr[i] = elements[i];}elements = newArr; //Caution!}private int calculateCapacity(int minCapacity) {if (minCapacity > MAX_CAPACITY || minCapacity < 0) {throw new ArrayListOverflowException();}// 一定能够容纳minCapacity个元素int newCapacity = elements.length + (elements.length >> 1);if (newCapacity > MAX_CAPACITY || newCapacity < 0) {newCapacity = MAX_CAPACITY;}// 返回minCapacity和newCapacity的最大值return minCapacity > newCapacity ? minCapacity : newCapacity;}private void checkIndexForAdd(int index) {if (index < 0 || index > size) {throw new IndexOutOfBoundsException("index=" + index + ", size=" + size);}}/*** 清空所有元素*/@Overridepublic void clear() {for (int i = 0; i < size; i++) {elements[i] = null;}size = 0;modCount++;}/*** 判断线性表中是否有与指定对象o相等的元素** @param o 指定对象* @return 如果存在与o相等的元素返回true, 否则返回false.*/@Overridepublic boolean contains(Object o) {return indexOf(o) != -1;}/*** 获取指定索引位置的元素** @param index 指定索引位置* @return 该索引位置的元素*/@Override@SuppressWarnings("unchecked")public E get(int index) {checkIndex(index);return (E) elements[index];}private void checkIndex(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("index=" + index + ", size=" + size);}}/*** 获取线性表中第一个与指定对象o相等元素的索引** @param o 指定对象* @return 第一个与指定对象o相等元素的索引, 如果线性表中没有这样的元素返回-1*/@Overridepublic int indexOf(Object o) {if (o == null) {for (int i = 0; i < size; i++) {if (elements[i] == null) return i;}} else {for (int i = 0; i < size; i++) {if (o.equals(elements[i])) return i;}}return -1;}/*** 获取线性表中最后一个与指定对象o相等元素的索引** @param o 指定对象* @return 最后一个与指定对象o相等元素的索引, 如果线性表中没有这样的元素返回-1*/@Overridepublic int lastIndexOf(Object o) {if (o == null) {for (int i = size - 1; i >= 0; i--) {if (elements[i] == null) return i;}} else {for (int i = size - 1; i >= 0; i--) {if (o.equals(elements[i])) return i;}}return -1;}/*** 判断线性表中是否包含元素** @return 如果没有元素, 返回true; 否则返回false*/@Overridepublic boolean isEmpty() {return size == 0;}/*** 删除指定索引位置的元素** @param index 指定索引位置* @return 被删除的元素*/@Override@SuppressWarnings("unchecked")public E remove(int index) {checkIndex(index);E removeValue = (E) elements[index];for (int i = index; i < size - 1; i++) {elements[i] = elements[i + 1];}elements[size - 1] = null;  // 为了避免内存泄漏size--;modCount++;return removeValue;}/*** 删除第一个与指定对象o相等的元素** @param o 指定对象* @return 如果删除成功返回true, 否则返回false*/@Overridepublic boolean remove(Object o) {int index = indexOf(o);if (index != -1) {remove(index);return true;}return false;}/*** 替换指定索引位置的元素** @param index 指定索引位置* @param e     新值* @return 旧值*/@Override@SuppressWarnings("unchecked")public E set(int index, E e) {checkIndex(index);E oldValue = (E) elements[index];elements[index] = e;return oldValue;}/*** 获取线性表中元素的个数** @return 性表中元素的个数*/@Overridepublic int size() {return size;}@Overridepublic String toString() {StringBuilder sb = new StringBuilder("[");for (int i = 0; i < size; i++) {sb.append(elements[i]).append(", ");}if (size > 0) sb.delete(sb.length() - 2, sb.length());return sb.append("]").toString();}/*** 返回一个迭代器, 光标后面的元素的索引为 0** @return 迭代器*/@Overridepublic MyIterator<E> iterator() {return new Itr();}/*** 返回一个迭代器, 光标后面的元素的索引为 index** @param index 光标后面的元素的索引* @return 迭代器*/@Overridepublic MyIterator<E> iterator(int index) {checkIndexForAdd(index);return new Itr(index);}private class Itr implements MyIterator<E> {// 属性int cursor; // 下一个元素的索引int expModCount = modCount;int lastRet = -1; // 最近返回元素的索引,-1表示最近没有返回元素, 或者是最近返回的元素失效了// 构造方法Itr() {}Itr(int index) {cursor = index;}/*** 判断光标后面是否有元素** @return 如果光标后面还有元素返回true, 否则返回false*/@Overridepublic boolean hasNext() {return cursor != size;}/*** 将光标往后移动一个位置, 并将越过的元素返回** @return 被光标越过的元素*/@Override@SuppressWarnings("unchecked")public E next() {// 判断迭代器是否失效checkConModException();if (!hasNext()) {throw new NoSuchElementException();}/*E retValue = (E) elements[cursor];lastRet = cursor;cursor++;return retValue;*/lastRet = cursor;return (E) elements[cursor++];}private void checkConModException() {if (expModCount != modCount) {throw new ConcurrentModificationException();}}/*** 判断光标前面是否有元素** @return 如果光标前面是有元素返回true, 否则返回false*/@Overridepublic boolean hasPrevious() {return cursor != 0;}/*** 将光标往前移动一个位置, 并把被光标越过的元素返回** @return 被光标越过的元素*/@Override@SuppressWarnings("unchecked")public E previous() {checkConModException();if (!hasPrevious()) {throw new NoSuchElementException();}/*cursor--;E retValue = (E)elements[cursor];lastRet = cursor;return retValue;*/lastRet = --cursor;return (E) elements[cursor];}/*** 获取光标后面元素的索引** @return 光标后面元素的索引*/@Overridepublic int nextIndex() {return cursor;}/*** 获取光标前面元素的索引** @return 光标前面元素的索引*/@Overridepublic int previousIndex() {return cursor - 1;}/*** 在光标后面添加元素** @param e 待添加的元素*/@Overridepublic void add(E e) {checkConModException();// 如何复用MyArrayList的add(int index, E e)方法呢?MyArrayList.this.add(cursor, e);expModCount = modCount;lastRet = -1;cursor++; // 保证插入的顺序与存储的顺序一致}/*** 删除最近返回的元素*/@Overridepublic void remove() {checkConModException();if (lastRet == -1) {throw new IllegalStateException();}MyArrayList.this.remove(lastRet);expModCount = modCount;// 如何移动cursor呢?cursor = lastRet; // Caution!lastRet = -1;}/*** 替换最近返回的元素** @param e 新值*/@Overridepublic void set(E e) {checkConModException();if (lastRet == -1) {throw new IllegalStateException();}elements[lastRet] = e;lastRet = -1;}}

MyIterator迭代器

import java.util.Iterator;public interface MyIterator<E> extends Iterator<E> {void add(E e);boolean hasNext();boolean hasPrevious();E next();int nextIndex();E previous();int previousIndex();void remove();void set(E e);
}

MyList链表

public interface MyList<E> extends Iterable<E> {boolean add(E e);void add(int index, E element);void clear();boolean contains(Object o);E get(int index);int indexOf(Object o);int lastIndexOf(Object o);boolean isEmpty();MyIterator<E> iterator();MyIterator<E> iterator(int index);E remove(int index);boolean remove(Object o);E set(int index, E element);int size();
}

ArrayListOverflowException

public class ArrayListOverflowException extends RuntimeException{public ArrayListOverflowException() {}public ArrayListOverflowException(String message) {super(message);}
}

Phase2 DAY5 MyArrayList相关推荐

  1. Spark菜鸟学习营Day5 分布式程序开发

    Spark菜鸟学习营Day5 分布式程序开发 这一章会和我们前面进行的需求分析进行呼应,完成程序的开发. 开发步骤 分布式系统开发是一个复杂的过程,对于复杂过程,我们需要分解为简单步骤的组合. 针对每 ...

  2. 《从零开始学Swift》学习笔记(Day5)——我所知道的标识符和关键字

     Swift 2.0学习笔记(Day5)--我所知道的标识符和关键字   原创文章,欢迎转载.转载请注明:关东升的博客 好多计算机语言都有标识符和关键字,一直没有好好的总结,就是这样的用着,现在小 ...

  3. Python学习day5作业-ATM和购物商城

    Python学习day5作业 Python学习day5作业 ATM和购物商城 作业需求 ATM: 指定最大透支额度 可取款 定期还款(每月指定日期还款,如15号) 可存款 定期出账单 支持多用户登陆, ...

  4. Python学习day5作业

    目录 Python学习day5作业 ATM和购物商城 1. 程序说明 2. 基本流程图 3. 程序测试帐号 4. 程序结构: 5. 程序测试 title: Python学习day5作业 tags: p ...

  5. Java基础day5

    Java基础day5 Java基础day5 1 方法的定义和调用 2 无参数方法的练习 3. 带参数方法的定义和调用 3.1 带参数放的定义和调用 3.2 形参和实参 3.3 带参数方法练习 4 带返 ...

  6. SpaceEmacs Rock Day5 学习笔记

    <?xml version="1.0" encoding="utf-8"?> SpaceEmacs Rock Day5 学习笔记 SpaceEmac ...

  7. 8.8 正睿暑期集训营 Day5

    目录 2018.8.8 正睿暑期集训营 Day5 总结 A 友谊巨轮(线段树 动态开点) B 璀璨光滑 C 构解巨树 考试代码 A B C 2018.8.8 正睿暑期集训营 Day5 时间:3.5h( ...

  8. #6073. 「2017 山东一轮集训 Day5」距离(树链剖分 + 永久标记主席树)

    #6073. 「2017 山东一轮集训 Day5」距离 给定一颗有nnn个节点带边权的树,以及一个排列ppp,path(u,v)path(u, v)path(u,v)为u,vu, vu,v路径上的点集 ...

  9. python atm作业详解_Python学习day5作业-ATM和购物商城

    Python学习day5作业 Python学习day5作业 ATM和购物商城 作业需求 ATM:指定最大透支额度 可取款 定期还款(每月指定日期还款,如15号) 可存款 定期出账单 支持多用户登陆,用 ...

  10. Java核心篇之泛型--day5

    Java核心篇之泛型–day5 泛型是JDK5时引入的一个新特性,泛型提供了编译时类型安全检查的机制,该机制允许程序猿在编译时检测到非法的类型输入. 泛型的本质是参数化类型,也就是说操作的类型被指定为 ...

最新文章

  1. Mac全量编译ijkplayer生成Android库
  2. [译]GLUT教程 - 每秒帧数
  3. Struts2 类型转换和数据校验
  4. 使用dbUnit,JSON,HSQLDB和JUnit规则进行数据库单元测试
  5. NYOJ-最少步数(dfs)
  6. 2021,前方路艰,与君共勉
  7. linux java 栈_JVM 与 Linux 的内存关系详解
  8. windows版redis安装教程
  9. MultiDesk远程桌面连接
  10. java中new对象_java new对象的理解
  11. 如何用VBA实现格式刷的功能?
  12. 有道翻译爬虫 js逆向
  13. Oracle系列之--Profile
  14. LSF集群基本概念介绍
  15. Java实现企业微信回调配置
  16. 【MySQL】在MySQL中如何给表起别名
  17. java干两年失业了,干了两年开发后,感觉快要被淘汰
  18. cmd导入数据到Oracle,oracle在cmd下通过命令导入导出数据
  19. 【技术贴】火狐QQ空间音乐插件下载+火狐进空间没背景音乐崩溃解决+火狐浏览器插件推荐...
  20. 2012.07.11

热门文章

  1. excel查找空值快捷键_『EXCEL定位条件快捷键』excel定位空值填充
  2. 《穿越计算机的迷雾》第一版说明
  3. 微信爬虫服务器,微信文章爬虫使用教程 - 八爪鱼采集器
  4. 【CAD二次开发】CAD常用版本 DwgVersion
  5. 2022年高压电工考试题模拟考试平台操作
  6. 最优化方法笔记-线性规划(大M法与两阶段法)
  7. 会员无损音乐各种格式转换成mp3等格式
  8. OpenSSL制作自签名V3证书
  9. cdrx4自动排版步骤_Coreldraw插件emboss使用方法 CDRX4的自动排版插件 百分之百显示问题...
  10. python写ppt_python可以写PPT吗