16、集合框架_LinkedList\Vertor
一、LinkedList增
1、add()添加值
public class LinkedListDemo { public static void main(String[] args) { LinkedList linkedList = new LinkedList(); linkedList.add(123); linkedList.add(false); linkedList.add("abc"); System.out.println(linkedList); } }
打印结果为:
/* [123, false, abc] Process finished with exit code 0 */
点进源码发现什么都没有
构造方法里并没有new的一个过程
每次add的时候创建一个节点
把next指向这个节点
2、add(index)
public class LinkedListDemo { public static void main(String[] args) { LinkedList linkedList = new LinkedList(); linkedList.add(123); linkedList.add(false); linkedList.add("abc"); System.out.println(linkedList); linkedList.add(2,"mashibing"); System.out.println(linkedList); linkedList.addFirst("1111"); System.out.println(linkedList); linkedList.addLast("2222"); System.out.println(linkedList); System.out.println(linkedList.element()); //调用getFirst() 拿第一个 linkedList.offer("3333"); // 调用add(e) System.out.println(linkedList); } }
/* [123, false, abc] [123, false, mashibing, abc] [1111, 123, false, mashibing, abc] [1111, 123, false, mashibing, abc, 2222] 1111 [1111, 123, false, mashibing, abc, 2222, 3333] Process finished with exit code 0 */
linkedList.add(2,"mashibing");
源码:
index是链表的大小, 新建节点
一种情况是空, 一种情况是插入到最后
为空就是新建一个新节点
不为空就是l.next 指向 新节点
现在的情况是
[123, false, abc]
linkedList.add(2,"mashibing");
index != size 执行 linkBefore(element, node(index)); (mashibing, node(index))
[123, false, abc]
拿到第二个节点的上一个 也就是pred = false
新建mashibing节点
将pred -> mashibing
二、Vector
1、基本使用
List里面有ArrayList、LinkedList、Vector
public class VectorDemo { public static void main(String[] args) { Vector vector = new Vector(); vector.add(1); vector.add("abc"); System.out.println(vector); } }
打印结果为:
/* [1, abc] Process finished with exit code 0 */
/** * 1、Vector也是List接口的一个子类实现 * 2、Vector跟ArrayList一样,底层都是使用数组进行实现的 * 3、面试经常问区别: * (1)ArrayList是线程不安全的,效率高,Vector是线程安全的效率低 * (2)ArrayList在进行扩容的时候,是扩容1.5倍,Vector扩容的时候扩容原来的2倍 * * */
ArrayList在扩容时
右移一位 /2 意味着1.5倍
Vector在扩容时
2、Iterator接口
所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象。
Iterator对象称作迭代器,用以方便的实现对容器内元素的遍历操作。
/* * 在java代码中包含三种循环的方式 * do...while * while * for * 还有一种增强for循环的方式,可以简化循环的编写 */
public class IteratorDemo { public static void main(String[] args) { ArrayList list= new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } //迭代器 Iterator iterator = list.iterator(); while(iterator.hasNext()){ Object o = iterator.next(); if(o.equals(1)){ iterator.remove(); } System.out.println(o); } for(Object i : list){ System.out.println(i); } } }
/* 1 2 3 4 1 2 3 4 2 3 4 Process finished with exit code 0 */
/* * 所有的集合类都默认实现了Iterable的接口,实现此接口意味着具备了增强for循环的能力,也就是for-each * 增强for循环本质上使用的也是iterator的功能 * 方法: * iterator() * foreach() * 在iterator的方法中,要求返回一个Iterator的接口子类实例对象 * 此接口中包含了 * hasNext() * next() */
ArrayList.java
cursor=0
lastRet=-1
corsor!=size
2.1、一遍遍历一遍删除
public class IteratorDemo { public static void main(String[] args) { ArrayList list= new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); //迭代器 Iterator iterator = list.iterator(); while(iterator.hasNext()){ Object o = iterator.next(); if(o.equals(1)){ list.remove(o); } System.out.println(o); } } }
打印结果为:
/* Exception in thread "main" java.util.ConcurrentModificationException 并发修改异常 at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:911) at java.util.ArrayList$Itr.next(ArrayList.java:861) */
指针都不知道指谁了,因为在list中删除了一个
public class IteratorDemo { public static void main(String[] args) { ArrayList list= new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } //迭代器 // Iterator iterator = list.iterator(); ListIterator iterator = list.listIterator(); while(iterator.hasNext()){ Object o = iterator.next(); if(o.equals(1)){ iterator.remove(); } System.out.println(o); } } }
2.2、也可以向前遍历
public class IteratorDemo { public static void main(String[] args) { ArrayList list= new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); //迭代器 // Iterator iterator = list.iterator(); ListIterator iterator = list.listIterator(); while(iterator.hasNext()){ Object o = iterator.next(); if(o.equals(1)){ iterator.remove(); } System.out.println(o); } System.out.println("-------------"); while (iterator.hasPrevious()){ System.out.println(iterator.previous()); } } }
打印结果为:
/* 1 2 3 4 ------------- 4 3 2 Process finished with exit code 0 */
如果只运行hasPrevious就会什么都不打印
import java.util.ArrayList; import java.util.ListIterator; public class IteratorDemo { public static void main(String[] args) { ArrayList list= new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); //迭代器 // Iterator iterator = list.iterator(); ListIterator iterator = list.listIterator(); // while(iterator.hasNext()){ // Object o = iterator.next(); // if(o.equals(1)){ // iterator.remove(); // } // System.out.println(o); // } System.out.println("-------------"); while (iterator.hasPrevious()){ System.out.println(iterator.previous()); } } }
打印结果为:
/* ------------- Process finished with exit code 0 */
因为正常指针会一直向下走,然后运行previous时,会拿到pre上一个
直接运行previous,在第一个在上一个就是空
/* * 在使用iterator进行迭代的过程中如果删除其中的某个元素会报错,并发操作异常,因此 * 如果遍历的同时需要修改元素,建议使用listIterator(), * ListIterator迭代器提供了向前和向后两种遍历的方式 * 始终是通过cursor和lastret的指针来获取元素值及向下的遍历索引 * 当使用向前遍历的时候必须要保证指针在迭代器的结尾,否则无法获取结果值 * */
2.3、增强for循环
public class IteratorDemo { public static void main(String[] args) { ArrayList list= new ArrayList(); list.add(1); list.add(2); list.add(3); list.add(4); for(Object i : list){ System.out.println(i); } } }
打印结果为:
/* 1 2 3 4 Process finished with exit code 0 */
三、练习
public class Dog { private String name; private String color; public Dog(){ } public Dog(String name, String color) { this.name = name; this.color = color; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } @Override public boolean equals(Object o) { if (this == o) return true; // o是传过来的参数 this是当前对象本身 比较的是地址,类里面一般比较属性 if (o == null || getClass() != o.getClass()) return false; Dog dog = (Dog) o; return Objects.equals(name, dog.name) && Objects.equals(color, dog.color); } @Override public int hashCode() { return Objects.hash(name, color); } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", color='" + color + '\'' + '}'; } }
public class ListTest { public static void main(String[] args) { List list = new ArrayList(); Dog d1 = new Dog("大黄","red"); Dog d2 = new Dog("二黄","block"); Dog d3 = new Dog("三黄","green"); list.add(d1); list.add(d2); list.add(d3); System.out.println(list); // 重写toString 打印的就不是对象 而是具体值了 System.out.println(list.size()); list.remove(d1); System.out.println(list); Dog d4 = new Dog("二黄","block"); System.out.println(list.contains(d4)); // 重写equals 和 hashcode 对比的就不是地址, 而是值了 } }