目录
Collection 接口遍历元素方式 1-使用 Iterator(迭代器)
Collection 接口遍历对象方式2 - for 循环增强
List 的三种遍历方式 [ArrayList, LinkedList,Vecto]
集合的理解和好处
数组
集合
集合的框架体系
Java 的集合类很多,主要分为两大类,如图 :[背下来]
1. 集合主要是两组(单列集合 , 双列集合)
2. Collection 接口有两个重要的子接口 List Set , 他们的实现子类都是单列集合
3. Map 接口的实现子类 是双列集合,存放的 K-Vpublic class Collection_ { @SuppressWarnings({"all"})//把警告去掉 public static void main(String[] args) { //1. 集合主要是两组(单列集合 , 双列集合) //2. Collection 接口有两个重要的子接口 List Set , //他们的实现子类都是单列集合 //3. Map 接口的实现子类 是双列集合,存放的 K-V //4. 把老师梳理的两张图记住 //Collection //Map ArrayList arrayList = new ArrayList(); arrayList.add("jack"); arrayList.add("tom"); System.out.println(arrayList.get(1)); HashMap hashMap = new HashMap(); hashMap.put("NO1", "北京"); hashMap.put("NO2", "上海"); System.out.println(hashMap.get("NO1")); } }
Collection 接口和常用方法
Collection 接口实现类的特点
接口是不能实例化的,只有实现接口的类才能被实例化。
public class CollectionMethod { @SuppressWarnings({"all"}) public static void main(String[] args) { List list = new ArrayList(); // add:添加单个元素 list.add("jack"); list.add(10);//10自动装箱:list.add(new Integer(10)) list.add(true); System.out.println("list=" + list); // remove:删除指定元素 list.remove(0);//删除第一个元素 list.remove(true);//指定删除某个元素 System.out.println("list=" + list); // contains:查找元素是否存在 System.out.println(list.contains("jack"));//T // size:获取元素个数 System.out.println(list.size());//2 // isEmpty:判断是否为空 System.out.println(list.isEmpty());//F // clear:清空 list.clear(); System.out.println("list=" + list); } }
public class CollectionMethod { @SuppressWarnings({"all"}) public static void main(String[] args) { List list = new ArrayList(); // addAll:添加多个元素 ArrayList list2 = new ArrayList(); list2.add("红楼梦"); list2.add("三国演义"); list.addAll(list2); System.out.println("list=" + list); // containsAll:查找多个元素是否都存在 System.out.println(list.containsAll(list2));//T // removeAll:删除多个元素 list.add("聊斋"); list.removeAll(list2); System.out.println("list=" + list);//[聊斋] } }
Collection 接口遍历元素方式 1-使用 Iterator(迭代器)
itertit
老师教大家一个快捷键,快速生成 while => itit, 显示所有的快捷键的的快捷键 ctrl + j
public class CollectionIterator { @SuppressWarnings({"all"}) public static void main(String[] args) { Collection col = new ArrayList(); col.add(new Book("三国演义", "罗贯中", 10.1)); col.add(new Book("小李飞刀", "古龙", 5.1)); col.add(new Book("红楼梦", "曹雪芹", 34.6)); System.out.println("col=" + col); //现在希望能够遍历 col集合 //1. 先得到 col 对应的 迭代器 Iterator iterator = col.iterator(); //2. 使用while循环遍历 // 老师教大家一个快捷键,快速生成 while => itit //显示所有的快捷键的的快捷键 ctrl + j while (iterator.hasNext()) {//判断是否还有数据 //返回下一个元素,类型是Object Object obj = iterator.next(); //编译类型是Object,运行类型取决于你真正存放的内容,这里是BOOK System.out.println("obj=" + obj); } // //3. 当退出while循环后 , 这时iterator迭代器,指向最后的元素 // // iterator.next();//NoSuchElementException // //4. 如果希望再次遍历,需要重置我们的迭代器 iterator = col.iterator(); System.out.println("===第二次遍历==="); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.println("obj=" + obj); } } } class Book { private String name; private String author; private double price; public Book(String name, String author, double price) { this.name = name; this.author = author; this.price = price; //set方法 //get方法 //tostring方法 } }
col=[Book{name='三国演义', author='罗贯中', price=10.1}, Book{name='小李飞刀', author='古龙', price=5.1}, Book{name='红楼梦', author='曹雪芹', price=34.6}]
当退出while循环后 , 这时iterator迭代器,指向最后的元素 。 如果执行iterator.next(),会有异常NoSuchElementException抛出。如果希望再次遍历,需要重置我们的迭代器:
iterator = col.iterator()。
再演示一下remove方法
Collection 接口遍历对象方式2 - for 循环增强
public class CollectionFor { @SuppressWarnings({"all"}) public static void main(String[] args) { Collection col = new ArrayList(); col.add(new Book("三国演义", "罗贯中", 10.1)); col.add(new Book("小李飞刀", "古龙", 5.1)); col.add(new Book("红楼梦", "曹雪芹", 34.6)); //1. 使用增强for, 在Collection集合 //2. 增强for, 底层仍然是迭代器 //3. 增强for可以理解成就是简化版本的 迭代器遍历 //4. 快捷键方式 大写I for (Object book : col) { System.out.println("book=" + book); } //增强for,也可以直接在数组使用 int[] nums = {1, 8, 10, 90}; for (int i : nums) { System.out.println("i=" + i); } } }
课堂练习
public class CollectionExercise { @SuppressWarnings({"all"}) public static void main(String[] args) { List list = new ArrayList(); list.add(new Dog("小黑", 3)); list.add(new Dog("大黄", 100)); list.add(new Dog("大壮", 8)); //先使用for增强 for (Object dog : list) { System.out.println("dog=" + dog); } //使用迭代器 System.out.println("===使用迭代器来遍历==="); Iterator iterator = list.iterator(); while (iterator.hasNext()) { Object dog = iterator.next(); System.out.println("dog=" + dog); } } } /** * 创建 3个 Dog {name, age} 对象,放入到 ArrayList 中,赋给 List 引用 * 用迭代器和增强for循环两种方式来遍历 * 重写Dog 的toString方法, 输出name和age */ class Dog { private String name; private int age; public Dog(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
List 接口和常用方法
List 接口基本介绍
List接口的实现类有很多种,但常用的是这三种。
public class List_ { @SuppressWarnings({"all"}) public static void main(String[] args) { //1. List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复 [案例] List list = new ArrayList(); list.add("jack"); list.add("mary"); list.add("hsp"); list.add("tom"); list.add("tom"); System.out.println("list=" + list); //2. List集合中的每个元素都有其对应的顺序索引,即支持索引 // 索引是从0开始的 System.out.println(list.get(1));//hsp } }
List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复 List集合中的每个元素都有其对应的顺序索引,即支持索引 索引是从0开始的。
List 接口的常用方法
public class ListMethod { @SuppressWarnings({"all"}) public static void main(String[] args) { List list = new ArrayList(); list.add("张三丰"); list.add("贾宝玉"); // void add(int index, Object ele):在index位置插入ele元素 //在index = 1的位置插入一个对象 list.add(1, "刘备"); System.out.println("list=" + list); // boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来 List list2 = new ArrayList(); list2.add("jack"); list2.add("tom"); list.addAll(1, list2); System.out.println("list=" + list); // Object get(int index):获取指定index位置的元素 //说过 // int indexOf(Object obj):返回obj在集合中首次出现的位置 System.out.println(list.indexOf("tom"));//2 // int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置 list.add("张三"); System.out.println("list=" + list); } }
public class ListMethod { @SuppressWarnings({"all"}) public static void main(String[] args) { List list = new ArrayList(); list.add("张三丰"); list.add("贾宝玉"); list.add("张三"); list.add("李四"); System.out.println(list); System.out.println(list.lastIndexOf("张三"));//2 // Object remove(int index):移除指定index位置的元素,并返回此元素 list.remove(0); System.out.println("list=" + list); // Object set(int index, Object ele):设置指定index位置的元素为ele , 相当于是替换. list.set(1, "玛丽"); System.out.println("list=" + list); // List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合 // 注意返回的子集合 包括0,不包括2 List returnlist = list.subList(0, 2); System.out.println("returnlist=" + returnlist); } }
练习
public class ListExercise { @SuppressWarnings({"all"}) public static void main(String[] args) { /* 添加10个以上的元素(比如String "hello" ),在2号位插入一个元素"韩顺平教育", 获得第5个元素,删除第6个元素,修改第7个元素,在使用迭代器遍历集合, 要求:使用List的实现类ArrayList完成。 */ List list = new ArrayList(); for (int i = 0; i < 12; i++) { list.add("hello" + i); } System.out.println("list=" + list); //在2号位插入一个元素"韩顺平教育" list.add(1, "韩顺平教育"); System.out.println("list=" + list); //获得第5个元素 System.out.println("第五个元素=" + list.get(4)); //删除第6个元素 list.remove(5); System.out.println("list=" + list); //修改第7个元素 list.set(6, "三国演义"); System.out.println("list=" + list); //在使用迭代器遍历集合 Iterator iterator = list.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.print(" " + obj); } } }
List 的三种遍历方式 [ArrayList, LinkedList,Vecto]
public class ListFor { @SuppressWarnings({"all"}) public static void main(String[] args) { //List 接口的实现子类 Vector LinkedList //List list = new ArrayList(); //List list = new Vector(); List list = new LinkedList(); list.add("jack"); list.add("tom"); list.add("鱼香肉丝"); list.add("北京烤鸭子"); //遍历 //1. 迭代器 Iterator iterator = list.iterator(); while (iterator.hasNext()) { Object obj = iterator.next(); System.out.println(obj); } System.out.println("=====增强for====="); //2. 增强for for (Object o : list) { System.out.println("o=" + o); } System.out.println("=====普通for===="); //3. 使用普通for for (int i = 0; i < list.size(); i++) { System.out.println("对象=" + list.get(i)); } } }
三种list的遍历的结果都一样
实现类的课堂练习2
创建一个Book类,get,set,tostring方法。
@SuppressWarnings({"all"}) public class ListExercise02 { public static void main(String[] args) { //List list = new ArrayList(); //List list = new LinkedList(); List list = new Vector(); list.add(new Book("红楼梦", "曹雪芹", 100)); list.add(new Book("西游记", "吴承恩", 10)); list.add(new Book("水浒传", "施耐庵", 19)); list.add(new Book("三国", "罗贯中", 80)); //list.add(new Book("西游记", "吴承恩", 10)); //如何对集合进行排序 //遍历 for (Object o : list) { System.out.println(o); } //冒泡排序 sort(list); System.out.println("==排序后=="); for (Object o : list) { System.out.println(o); } } //静态方法 //价格要求是从小到大 public static void sort(List list) { int listSize = list.size(); for (int i = 0; i < listSize - 1; i++) { for (int j = 0; j < listSize - 1 - i; j++) { //取出对象Book,向下转型 Book book1 = (Book) list.get(j); Book book2 = (Book) list.get(j + 1); if (book1.getPrice() > book2.getPrice()) {//交换 list.set(j, book2); list.set(j + 1, book1); } } } } }
ArrayList 底层结构和源码分析
@SuppressWarnings({"all"}) public class ArrayListSource { public static void main(String[] args) { //老韩解读源码 //注意,注意,注意,Idea 默认情况下,Debug 显示的数据是简化后的,如果希望看到完整的数据 //需要做设置. //使用无参构造器创建ArrayList对象 ArrayList list = new ArrayList(); //ArrayList list = new ArrayList(8); //使用for给list集合添加 1-10数据 for (int i = 1; i <= 10; i++) { list.add(i); } //使用for给list集合添加 11-15数据 for (int i = 11; i <= 15; i++) { list.add(i); } list.add(100); list.add(200); list.add(null); } }
看不懂去看视频
0510_韩顺平Java_ArrayList底层源码1_哔哩哔哩_bilibili
Vector 底层结构和源码剖析
Vector 的基本介绍
@SuppressWarnings({"all"}) public class Vector_ { public static void main(String[] args) { //无参构造器 //有参数的构造 Vector vector = new Vector(8); for (int i = 0; i < 10; i++) { vector.add(i); } vector.add(100); System.out.println("vector=" + vector); //老韩解读源码 //1. new Vector() 底层 /* public Vector() { this(10); } 补充:如果是 Vector vector = new Vector(8); 走的方法: public Vector(int initialCapacity) { this(initialCapacity, 0); } 2. vector.add(i) 2.1 //下面这个方法就添加数据到vector集合 public synchronized boolean add(E e) { modCount++; ensureCapacityHelper(elementCount + 1); elementData[elementCount++] = e; return true; } 2.2 //确定是否需要扩容 条件 : minCapacity - elementData.length>0 private void ensureCapacityHelper(int minCapacity) { // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } 2.3 //如果 需要的数组大小 不够用,就扩容 , 扩容的算法 //newCapacity = oldCapacity + ((capacityIncrement > 0) ? // capacityIncrement : oldCapacity); //就是扩容两倍. private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + ((capacityIncrement > 0) ? capacityIncrement : oldCapacity); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); elementData = Arrays.copyOf(elementData, newCapacity); } */ } }
Vector 和 ArrayList 的比较
LinkedList 底层结构
public class LinkedList01 { public static void main(String[] args) { //模拟一个简单的双向链表 Node jack = new Node("jack"); Node tom = new Node("tom"); Node hsp = new Node("老韩"); //连接三个结点,形成双向链表 //jack -> tom -> hsp jack.next = tom; tom.next = hsp; //hsp -> tom -> jack hsp.pre = tom; tom.pre = jack; Node first = jack;//让first引用指向jack,就是双向链表的头结点 Node last = hsp; //让last引用指向hsp,就是双向链表的尾结点 //演示,从头到尾进行遍历 System.out.println("===从头到尾进行遍历==="); while (true) { if(first == null) { break; } //输出first 信息 System.out.println(first); first = first.next; } //演示,从尾到头的遍历 System.out.println("====从尾到头的遍历===="); while (true) { if(last == null) { break; } //输出last 信息 System.out.println(last); last = last.pre; } //演示链表的添加对象/数据,是多么的方便 //要求,是在 tom --------- 老韩直接,插入一个对象 smith //1. 先创建一个 Node 结点,name 就是 smith Node smith = new Node("smith"); //下面就把 smith 加入到双向链表了 smith.next = hsp; smith.pre = tom; hsp.pre = smith; tom.next = smith; //让first 再次指向jack first = jack;//让first引用指向jack,就是双向链表的头结点 System.out.println("===从头到尾进行遍历==="); while (true) { if(first == null) { break; } //输出first 信息 System.out.println(first); first = first.next; } last = hsp; //让last 重新指向最后一个结点 //演示,从尾到头的遍历 System.out.println("====从尾到头的遍历===="); while (true) { if(last == null) { break; } //输出last 信息 System.out.println(last); last = last.pre; } } } //定义一个Node 类,Node 对象 表示双向链表的一个结点 class Node { public Object item; //真正存放数据 public Node next; //指向后一个结点 public Node pre; //指向前一个结点 public Node(Object name) { this.item = name; } public String toString() { return "Node name=" + item; } }
LinkedList 的增删改查案例
@SuppressWarnings({"all"}) public class LinkedListCRUD { public static void main(String[] args) { LinkedList linkedList = new LinkedList(); linkedList.add(1); linkedList.add(2); linkedList.add(3); System.out.println("linkedList=" + linkedList); //演示一个删除结点的 linkedList.remove(); // 这里默认删除的是第一个结点 //linkedList.remove(2); System.out.println("linkedList=" + linkedList); //修改某个结点对象 linkedList.set(1, 999); System.out.println("linkedList=" + linkedList); //得到某个结点对象 //get(1) 是得到双向链表的第二个对象 Object o = linkedList.get(1); System.out.println(o);//999 //因为LinkedList 是 实现了List接口, 遍历方式 System.out.println("===LinkeList遍历迭代器===="); Iterator iterator = linkedList.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println("next=" + next); } System.out.println("===LinkeList遍历增强for===="); for (Object o1 : linkedList) { System.out.println("o1=" + o1); } System.out.println("===LinkeList遍历普通for===="); for (int i = 0; i < linkedList.size(); i++) { System.out.println(linkedList.get(i)); } //老韩源码阅读. /* 1. LinkedList linkedList = new LinkedList(); public LinkedList() {} 2. 这时 linkeList 的属性 first = null last = null 3. 执行 添加 public boolean add(E e) { linkLast(e); return true; } 4.将新的结点,加入到双向链表的最后 void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; } */ /* 老韩读源码 linkedList.remove(); // 这里默认删除的是第一个结点 1. 执行 removeFirst public E remove() { return removeFirst(); } 2. 执行 public E removeFirst() { final Node<E> f = first; if (f == null) throw new NoSuchElementException(); return unlinkFirst(f); } 3. 执行 unlinkFirst, 将 f 指向的双向链表的第一个结点拿掉 private E unlinkFirst(Node<E> f) { // assert f == first && f != null; final E element = f.item; final Node<E> next = f.next; f.item = null; f.next = null; // help GC first = next; if (next == null) last = null; else next.prev = null; size--; modCount++; return element; } */ } }
ArrayList 和 LinkedList 比较