集合框架· ArrayList 和 Vector

对象数组的概述和使用

* A:案例演示
  * 需求:我有5个学生,请把这5个学生的信息存储到数组中,并遍历数组,获取到每个学生的信息

Student[] arr = new Student[5];
arr[0] = new Student("张三", 23);
arr[1] = new Student("李四", 24);
arr[2] = new Student("王五", 25);
arr[3] = new Student("赵六", 26);
arr[4] = new Student("周七", 27); for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}

* B:画图演示
  * 把学生数组的案例画图讲解
  * 数组和集合存储引用数据类型,存的都是地址值

package com.heima.collection;

import com.heima.bean.Student;

public class Demo1_Array {
public static void main(String[] args) {
// int[] arr = new int[5]; // 创建基本数据类型数组
Student[] arr = new Student[5]; // 创建引用数据类型数组
arr[0] = new Student("张三", 23); // 创建一个学生对象,存储在数组的第一个位置
arr[1] = new Student("李四", 24);
arr[2] = new Student("王五", 25); for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]); // 默认调用toString的方法,如果Student类没有重写toString方法,则默认调用Object类的方法
}
}
}

Collection

集合的由来及集合继承体系图

* A:集合的由来
  * 数组的长度是固定的,当添加的元素超过了数组的长度时需要对数组重新定义
  * Java内部给我们提供了集合类,能存储任意对象,长度可以改变,随着元素的增加而增加

* B:数组和集合的区别
  * 区别一:
    * 数组 既可以存储基本数据类型,又可以存储引用数据类型;基本数据类型存储的是值,引用数据类型存储的是地址值
    * 集合 只能存储引用数据类型;如果要存储基本数据类型,就需要进行装箱

  * 区别二:
    * 数组的长度是固定的,不能自动增长
    * 集合的长度是可变的,可以根据元素的增加而增长

* C:数组和集合什么时候用
  * 如果元素的个数是固定的,推荐用数组
  * 如果元素的个数不是固定的,推荐用集合

* D:集合继承体系图

Collection集合的基本功能测试

* A:案例演示

基本功能演示

boolean add(E e)
boolean remove(Object o)
void clear()
boolean contains(Object o)
boolean isEmpty()
int size()

* B:注意
  * collectionXxx.java 使用了未经检查或不安全的操作
    * 要了解详细信息,请使用 -Xlint:inchecked 重新编译
    * java编译器认为该程序存在安全隐患

    public String toString() {
Iterator<E> it = iterator();
if (! it.hasNext())
return "[]"; StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}

toString

package com.heima.collection;

import java.util.ArrayList;
import java.util.Collection; import com.heima.bean.Student; @SuppressWarnings({ "rawtypes", "unchecked" }) public class Demo2_Collection {
public static void main(String[] args) {
Collection c = new ArrayList(); // 父类引用指向子类对象
// demo1(c);
demo2(c);
} public static void demo2(Collection c) {
c.add("a");
c.add("b");
c.add("c");
c.add("d"); c.remove("c"); // 删除指定元素
System.out.println(c); System.out.println(c.contains("a")); // 判断是否包含指定元素 c.clear(); // 彻底清空集合
System.out.println(c);
System.out.println(c.isEmpty()); // 判断是否是空集合
System.out.println(c.size()); // 获取集合中包含的元素的个数,类似于字符串中的length()方法
} public static void demo1(Collection c) {
// add方法: 如果是List集合,一直都返回true,因为List集合中是可以存储重复元素的
// 如果是set 集合,当存储重复元素时,就会返回false boolean b1 = c.add("abc"); // 可以添加任意对象,任意对象都是Object的子类
boolean b2 = c.add(true); // 自动装箱 new Boolean(true);
boolean b3 = c.add(100); // 自动装箱 new Integer(100);
boolean b4 = c.add(new Student("张三", 23));
boolean b5 = c.add("abc"); // 都是true
System.out.println(b1);
System.out.println(b2);
System.out.println(b3);
System.out.println(b4);
System.out.println(b5); System.out.println(c); // ArrayList的爷爷类重写了toString方法
}
}

ArrayList

集合转数组遍历

* A:集合的遍历
  * 其实就是依次获取集合中的每一个元素

* B:案例演示
  * 把集合转换成数组,可以实现集合的遍历
  * toArray()

Collection c = new ArrayList();
c.add(new Student("张三", 23)); // Object obj = new Student("张三", 23)
c.add(new Student("李四", 24));
c.add(new Student("王五", 25));
c.add(new Student("赵六", 26)); Object[] arr = coll.toArray; // 将集合转换为数组
for (int i = 0; i < arr.length; i++) {
  Student s = (Student)arr[i]; // 强转成Student
  System.out.println(s.getName() + "," + s.getAge());
}

package com.heima.collection;

import java.util.ArrayList;
import java.util.Collection; import com.heima.bean.Student; @SuppressWarnings({ "rawtypes", "unchecked" })
public class Demo3_Collection {
public static void main(String[] args) {
// demo1();
// demo2(); } public static void demo2() {
Collection c = new ArrayList();
c.add(new Student("张三", 23)); // 向数组内存入自定义的引用对象
c.add(new Student("李四", 24));
c.add(new Student("王五", 25));
c.add(new Student("赵六", 26)); Object[] arr = c.toArray(); // 向上转型 提升为Object类
for (int i = 0; i < arr.length; i++) {
// System.out.println(arr[i]);
Student s = (Student) arr[i]; // 强制向下转型
System.out.println(s.getName() + "..." + s.getAge());
}
} public static void demo1() {
Collection c = new ArrayList();
c.add("a");
c.add("b");
c.add("c");
c.add("d"); Object[] arr = c.toArray(); // 将集合转换成数组
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}

ArrayList

Collection集合的带All功能测试

* A:案例演示

带All的功能演示

boolean addAll(Collection c)
boolean removeAll(Collection c)
boolean containsAll(Collection c)
boolean retainAll(Collection c)
package com.heima.collection;

import java.util.ArrayList;
import java.util.Collection; public class Demo4_Collection {
public static void main(String[] args) {
// demo1(); // 整体添加
// demo2(); // 删除交集
// demo3(); // 是否包含
// demo4(); // 取交集
} public static void demo4() {
Collection c1 = new ArrayList();
c1.add("a");
c1.add("b");
c1.add("c");
c1.add("d"); Collection c2 = new ArrayList();
c2.add("a");
c2.add("b");
c2.add("z");
c2.add("c");
c2.add("d"); boolean b = c1.retainAll(c2); // 取交集,如果调用的集合改变就返回true,如果调用的集合不变就返回false
System.out.println(b);
System.out.println(c1);
} public static void demo3() {
Collection c1 = new ArrayList();
c1.add("a");
c1.add("b");
c1.add("c");
c1.add("d"); Collection c2 = new ArrayList();
c2.add("a");
c2.add("b");
c2.add("z"); boolean b = c1.containsAll(c2); // 判断调用的集合是否包含传入的集合,如果出现一个元素不包含就返回false,可以有重复
System.out.println(b);
} public static void demo2() {
Collection c1 = new ArrayList();
c1.add("a");
c1.add("b");
c1.add("c");
c1.add("d"); Collection c2 = new ArrayList();
c2.add("a");
c2.add("b");
c2.add("z"); boolean b = c1.removeAll(c2); // 如果有交集,就删除并返回true; 如果没有交集就不删除并且返回false
System.out.println(b);
System.out.println(c1);
} public static void demo1() {
Collection c1 = new ArrayList();
c1.add("a");
c1.add("b");
c1.add("c");
c1.add("d"); Collection c2 = new ArrayList(); // alt + shift + r 可以整体改名
c2.add("a");
c2.add("b");
c2.add("c");
c2.add("d"); c1.addAll(c2); // 将c2中的每一个元素都 添加到c1中
c1.add(c2); // 将c2整个集合看成 一个对象 添加到c1中
System.out.println(c1);
}
}

ArrayList

迭代器遍历

* A:迭代器概述
  * 集合是用来存储元素的,存储的元素要查看,那么就需要迭代(遍历)

* 案例演示

迭代器的使用

Collection c = new ArrayList();
c.add("a");
c.add("b");
c.add("c");
c.add("d"); Iterator it = c.iterator(); while (it.hasNext()) {
System.out.println(it.next());
}

package com.heima.collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; import com.heima.bean.Student; public class Demo5_Collection {
public static void main(String[] args) {
// demo1();
// demo2();
} public static void demo2() {
// 迭代自定义类
Collection c = new ArrayList();
c.add(new Student("张三", 23)); // 自动提升为Object类
c.add(new Student("李四", 24));
c.add(new Student("王五", 25));
c.add(new Student("赵六", 26));
// 获取迭代器
Iterator it = c.iterator();
while (it.hasNext()) {
// System.out.println(it.next());
Student s = (Student) it.next(); // 向下转型,注意next方法调用时的指针位置变化
System.out.println(s.getName() + "..." + s.getAge());
}
} public static void demo1() {
Collection c = new ArrayList();
c.add("a");
c.add("b");
c.add("c");
c.add("d"); // 对集合中的元素进行迭代(遍历)
Iterator it = c.iterator(); // 获取迭代器
/*
* boolean b1 = it.hasNext(); // 判断集合中是否有元素
* System.out.println(b1); //
* Object obj1 = it.next(); // next方法获取相应元素,并且将指针向后移动一位
* System.out.println(obj1);
*/ while (it.hasNext()) {
System.out.println(it.next());
}
}
}

Iterator

迭代器的原理和源码解析

* A:迭代器原理
  * 迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以没一个集合的存和取的方式都是不一样的
  * 那么这就需要在每一个类中定义hasNext() 和 next() 方法,这样做可以但是会使集合体系过于臃肿
  * 迭代器就是将这样的方法向上抽取出接口,然后在每个类的内部,定义自己的迭代方法
  * 好处:1、规定了整个集合体系的遍历方式都是hasNext() 和next() 方法;2、代码由底层内部实现,使用者不用管怎么实现,会用即可

* B:迭代器源码分析
  * 1、在eclipse 中ctrl + shift + t 找到ArrayList类
  * 2、ctrl + o 查找 iterator() 方法
  * 3、查看返回值类型是new Itr(), 说明Itr这个类实现 Iterator接口
  * 4、查找 Itr这个内部类,发现重写了 Iterator中的所有抽象方法

    private class Itr implements Iterator<E> {
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount; // prevent creating a synthetic constructor
Itr() {} public boolean hasNext() {
return cursor != size;
} @SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
} public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification(); try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}

Iterator源码

List集合的特有功能概述和测试

* A:List集合的特有功能概述

void add(int index, E element)
E remove(int index)
E get(int index)
E set(int index, E element)

package com.heima.list;

import java.util.ArrayList;
import java.util.List; public class Demo1_List {
public static void main(String[] args) {
// demo1(); // 元素添加
// demo2(); // 元素删除
// demo3(); // remove 注意点
// demo4(); // 通过索引获取元素
// demo5(); // 指定元素修改
} public static void demo5() {
List list = new ArrayList();
list.add(0, "a");
list.add(0, "b");
list.add(0, "c");
list.add(0, "d"); list.set(1, "z"); // 将指定位置的元素修改
System.out.println(list);
} public static void demo4() {
List list = new ArrayList();
list.add(0, "a");
list.add(0, "b");
list.add(0, "c");
list.add(0, "d"); // Object obj1 = list.get(0);
// System.out.println(obj1);
// 通过索引遍历List集合
for (int i = 0; i < list.size(); i++) { // 用 size() 方法
System.out.println(list.get(i));
}
} public static void demo3() {
List list = new ArrayList();
list.add(111);
list.add(222);
list.add(333);
list.add(444); Object obj1 = list.remove(111); // 删除的时候不会自动装箱,111被当成索引,下标就越界了
System.out.println(obj1);
} public static void demo2() {
List list = new ArrayList();
list.add(0, "a");
list.add(0, "b");
list.add(0, "c");
list.add(0, "d"); Object obj1 = list.remove(0); // 通过索引删除元素,将被删除的元素返回
System.out.println(obj1);
System.out.println(list);
} public static void demo1() {
List list = new ArrayList(); // 多态,有弊端,不能访问子类的特有属性
list.add("a");
list.add("b");
list.add(0, "c"); // index是元素添加后所在的位置
list.add(0, "d");
// list.add(5, "e"); // 注意索引越界异常,0<=index<=size
System.out.println(list);
}
}

List

List集合存储学生对象并遍历

* A:案例演示
  * 通过size() 和get() 方法结合使用遍历

package com.heima.list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; import com.heima.bean.Student; public class Demo2_List { public static void main(String[] args) {
List list = new ArrayList();
list.add(new Student("张三", 23)); // 自动向上转型为Object
list.add(new Student("李四", 24));
list.add(new Student("王五", 25));
list.add(new Student("赵六", 26)); for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i)); // 通过索引获取每一个元素
Student stu = (Student) list.get(i);
System.out.println(stu.getName() + "..." + stu.getAge());
}
}
}

Test1

并发修改异常

* A:案例演示
  * 需求:如果有一个集合,判断集合内是否有 "world" 这个元素,如果有,就添加一个 "javaee" 元素

List list = new ArrayList();
list.add("a");
list.add("b");
list.add("world");
list.add("c");
list.add("d");
list.add("e"); ListIterator it = list.listIterator();
while (it.hasNext()) {
Object object = it.next();
System.out.println(object);
if (object.equals("world")) {
list.add("javaee");
it.add("javaee");
} }

* B:ConcurrentModificationException出现
  * 迭代器遍历,集合修改集合

* C:解决方案
  * a:迭代器迭代元素,迭代器修改元素 (ListIterator的特有功能 add)
  * b:集合遍历元素,集合修改元素

ListIterator lit = list.listIterator;  // 如果向在遍历的过程中添加元素,可以用ListIterator中的add方法
while(lit.hasNext()) {
  String str = (String)lit.next;
  if(str.equals("world")) {
  lit.add("javaee");
 }
}

package com.heima.list;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator; public class Demo3_List {
public static void main(String[] args) {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("world");
list.add("c");
list.add("d");
list.add("e"); ListIterator it = list.listIterator(); // 获取迭代器
while (it.hasNext()) { // 判断集合中是否有元素
String object = (String) it.next(); // 向下转型
if (object.equals("world")) {
// list.add("javaee"); // 遍历的同时在增加元素,产生并发修改异常
it.add("javaee");
}
}
System.out.println(list); }
}

ListIterator

ListIterator

boolean hasNext()
boolean hasPrevious() Object next()
Object previous()
package com.heima.list;

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator; public class Demo4_ListIterator {
public static void main(String[] args) {
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("world");
list.add("c");
list.add("d");
list.add("e"); ListIterator lit = list.listIterator(); // 获取迭代器
while (lit.hasNext()) {
System.out.println(lit.next()); // 获取元素,并将指针向后移动
} System.out.println("-----------"); while (lit.hasPrevious()) {
System.out.println(lit.previous()); // 获取元素,并将指针向前移动
} }
}

ListIterator

Vector的特有功能

* A:Vector类概述

* B:Vector类特有功能

public void addElements(E obj)
public E elementAt(int index)
public Enumeration elements()

* C:案例演示
  * Vector迭代

package com.heima.list;

import java.util.Enumeration;
import java.util.Vector; public class Demo5_Vector { public static void main(String[] args) {
Vector v = new Vector();
v.addElement("a");
v.addElement("b");
v.addElement("c");
v.addElement("d"); Enumeration en = v.elements(); // 获取枚举
while (en.hasMoreElements()) { // 判断集合中是否有元素
System.out.println(en.nextElement()); // 获取集合中的元素
}
}
}

Vector

数据结构之数组和链表

* A:数组
  * 查询快,修改也快
  * 增删慢

* B:链表
  * 查询慢,修改野蛮
  * 增删快

Node<E> node(int index) {
// assert isElementIndex(index); if (index < (size >> 1)) {
Node<E> x = first;
for (int i = 0; i < index; i++)
x = x.next;
return x;
} else {
Node<E> x = last;
for (int i = size - 1; i > index; i--)
x = x.prev;
return x;
}
}

LinkedList源码 明确查找元素从哪里开始

List的三个子类的特点

* A:List的三个子类的特点

  * ArrayList:
    底层数据结构是数组,查询快,增删慢
    线程不安全,效率高

  * Vector:
    底层数据结构是数组,查询快,增删慢
    线程安全,效率低
    Vector相对ArrayList查询慢(线程安全)
    Vector相对LinkedList增删满(数据结构)

  * LinkedList:
    底层数据结构是链表,查询慢,增删快
    线程不安全,效率高

  * Vector和ArrayList的区别
    Vector是线程安全的,效率低
    ArrayList是线程不安全的,效率高
    共同的:都是数组实现的

  * ArrayList和LinkedList的区别
    ArrayList底层是数组结构,查询和修改快
    LinkedList底层是链表结构,查询慢修改快
    共同的:都是线程不安全的

* List的三个儿子的使用
  * 查询多  -> ArrayList
  * 增删多  -> LinkedList
  * 都多     -> ArrayList

  * Vector一般只在面试的时候会问

Java 集合框架 01的更多相关文章

  1. java集合框架01——总体框架一览

    java集合框架是java提供的工具包,在java.util.*中,这个包中包含了常用的数据结构:集合.数组.链表.栈.队列.映射等.java集合框架主要可以分为四个部分:List列表.Set集合.M ...

  2. java集合框架01

    List 接口存储一组不唯一(可以重复),有序(插入顺序)的对象 01. ArrayList实现了长度可变的数组,在内存中分配连续的空间.遍历元素和随机访问元素的效率比较高 通过看ArrayList的 ...

  3. Java 集合系列 01 总体框架

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  4. Java集合框架Collection

    转自:http://www.cdtarena.com/javapx/201306/8891.html [plain] view plaincopyprint?01.在 Java2中,有一套设计优良的接 ...

  5. Java集合框架之四大接口、常用实现类

    Java集合框架 <Java集合框架的四大接口> Collection:存储无序的.不唯一的数据:其下有List和Set两大接口. List:存储有序的.不唯一的数据: Set:存储无序的 ...

  6. java集合框架容器 java框架层级 继承图结构 集合框架的抽象类 集合框架主要实现类

    本文关键词: java集合框架  框架设计理念  容器 继承层级结构 继承图 集合框架中的抽象类  主要的实现类 实现类特性   集合框架分类 集合框架并发包 并发实现类 什么是容器? 由一个或多个确 ...

  7. 【转载】Java 集合框架

    http://wangkuiwu.github.io/2012/02/03/collection-03-arraylist/ 网上比较全的Java集合框架教程. 注:transient是Java语言的 ...

  8. Java集合框架之Vector浅析

    Java集合框架之Vector浅析 一.Vector概述: 位于java.util包下的Vector是Java集合框架的重要一员,虽然没有ArrayList那么的常用,但是我们还要对其做相关学习: 1 ...

  9. Java集合框架之LinkedList浅析

    Java集合框架之LinkedList浅析 一.LinkedList综述: 1.1LinkedList简介 同ArrayList一样,位于java.util包下的LinkedList是Java集合框架 ...

随机推荐

  1. HDU 3537 Daizhenyang's Coin 翻硬币博弈

    题意: 给你n个硬币,你可以从中拿出来1.2.3个硬币,它们不一定要连续,你只需要保证拿出来的硬币中那个下标最大的硬币一定要是正面朝上,最后谁不能操作,谁就输了 题解: 翻硬币游戏 结论: 局面的SG ...

  2. Codeforces Round #656 (Div. 3) A. Three Pairwise Maximums (数学)

    题意:给你三个正整数\(x\),\(y\),\(z\),问能够找到三个正整数\(a\),\(b\),\(c\),使得\(x=max(a,b)\),\(y=max(a,c)\),\(z=max(b,c) ...

  3. 洛谷P1462-通往奥格瑞玛的道路-二分+最短路

    洛谷P1462-通往奥格瑞玛的道路 题目描述 在艾泽拉斯,有\(n\)个城市.编号为\(1,2,3,...,n\). 城市之间有\(m\)条双向的公路,连接着两个城市,从某个城市到另一个城市,会遭到联 ...

  4. 并发编程之java内存模型(Java Memory Model ,JMM)

    一.图例 0.两个概念 Heap(堆):运行时的数据区,由垃圾回收负责,运行时分配内存(所以慢),对象存放在堆上 如果两个线程,同时调用同一个变量,怎两个线程都拥有,该对象的私有拷贝 (可以看一下,T ...

  5. 牛客网多校第7场 J Sudoku Subrectangles 【构造】

    题目:戳这里 题意:给一个n*m的矩阵,里面由a~z及A~Z构成,问有多少个子矩阵满足任意一行或一列中都没有相同的字母. 解题思路:左上角和右下角两点可以确定一个矩阵.可以先预处理出来每个点作为一个矩 ...

  6. codeforces 869A

    A. The Artful Expedient time limit per test 1 second memory limit per test 256 megabytes input stand ...

  7. mssql数据库提权(xp_cmdshell)

    1.关于 "xp_cmdshell" "存储过程":其实质就是一个"集合",那么是什么样的结合呢,就是存储在SqlServer中预先定义好的 ...

  8. Python求二维数组中某列的最大值

    主要运用np.amax() import numpy as np help(np.amax) a = np.arange(9).reshape((3, 3)) max_all = np.amax(a) ...

  9. CSS字体大小: em与px、pt、百分比之间的对比

      CSS样式最混乱的一个方面是应用程序中文本扩展的font-size属性.在CSS中,你可以用四个不同的单位度量来显示在web浏览器中的文本大小.这四个单位哪一种最适合Web? 这个问题引起了广泛的 ...

  10. MobX All In One

    MobX All In One Simple, scalable state management. https://mobx.js.org/README.html https://github.co ...