> 文章列表 > 集合,Collection接口,Iterator(迭代器),List接口和方法,ArrayList底层结构和源码分析

集合,Collection接口,Iterator(迭代器),List接口和方法,ArrayList底层结构和源码分析

集合,Collection接口,Iterator(迭代器),List接口和方法,ArrayList底层结构和源码分析

  1. 数组的不足
    1. 长度开始必须指定,而且一旦指定,不能修改
    2. 保存的必须为同一类型的元素
    3. 使用数组进行增加/删除元素的示意代码麻烦
    4. @SuppressWarnings({"all"})抑制警告
  2. 集合
    1. 可以动态保存任意多个对象,使用比较方便
    2. 提供了一系列方便的操作对象的方法:add,remove,set,get等
    3. 使用集合添加,删除新元素的示意代码简洁
  3. 集合主要是两组(单列集合,双列集合)
    1. 单列集合,
    2.  双列集合存放K-V(键值对)
  4. Collection接口和常用方法
    1. collection实现子类可以存放多个元素,每个元素可以是Object
    2. 有些Collection的实现类,可以存放重复的元素,有些不可以
    3. 有些Collection的实现类,有些是有序的(List),有些不是有序(Set)
    4. Collection接口没有直接的实现子类,是通过它的子接口Set和List来实现的。
    5. 常用方法
      package com.jshedu.collection;import java.util.ArrayList;
      import java.util.List;/* @author 韩顺平* @version 1.0*/
      public class CollectionMethod {@SuppressWarnings({"all"})public static void main(String[] args) {List list = new ArrayList();
      //        add:添加单个元素list.add("jack");list.add(10);//list.add(new Integer(10))list.add(true);System.out.println("list=" + list);//list=[jack, 10, true]
      //        remove:删除指定元素//list.remove(0);//删除第一个元素list.remove(true);//指定删除某个元素System.out.println("list=" + list);//list=[jack, 10]
      //        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);//list=[]
      //        addAll:添加多个元素ArrayList list2 = new ArrayList();list2.add("红楼梦");list2.add("三国演义");list.addAll(list2);System.out.println("list=" + list);//list=[红楼梦, 三国演义]
      //        containsAll:查找多个元素是否都存在System.out.println(list.containsAll(list2));//T
      //        removeAll:删除多个元素list.add("聊斋");list.removeAll(list2);System.out.println("list=" + list);//[聊斋]
      //        说明:以ArrayList实现类来演示.}
      }
      

      以ArrayList实现类来演示(ctrl+j显示所有快捷键)

  5. Collection接口遍历元素方式1-使用Iterator(迭代器)

    1. iterator对象称为迭代器,主要用于遍历Collection集合中的元素

    2. 所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现Iterator接口的对象,即可以返回一个迭代器

    3. iterator仅用于遍历集合,Iterator本身并不存放对象

    4. 在调用next()方法前必须调用hasNext()进行检测。若不调用且下一条记录无效,直接调用next()会抛出NoSuchElementException异常

    5. package com.jshedu.collection;import java.util.ArrayList;
      import java.util.Collection;
      import java.util.Iterator;
      import java.util.NoSuchElementException;/* @author Mr.jia* @version 1.0*/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("小李飞刀","古龙",12.1));col.add(new BooK("红楼梦","曹雪芹",9.1));//col=[BooK{name='三国演义', author='罗贯中', price=10.1},// BooK{name='小李飞刀', author='古龙', price=12.1},// BooK{name='红楼梦', author='曹雪芹', price=9.1}]//System.out.println("col="+col);//现在希望能够遍历col集合//1.先得到col对应的 迭代器Iterator iterator = col.iterator();//返回迭代器//2.使用while循环遍历。。。快捷键生成while-->ititwhile (iterator.hasNext()){//这个方法是判断下面是否还有数据//返回下一个元素,类型是ObjectObject obj = iterator.next();//next()1.下移,2.将下移以后集合位置上的元素返回System.out.println("obj="+obj);/*obj=BooK{name='三国演义', author='罗贯中', price=10.1}obj=BooK{name='小李飞刀', author='古龙', price=12.1}obj=BooK{name='红楼梦', author='曹雪芹', price=9.1}*/}//3.当退出while循环后,这时iterator迭代器,指向最后的元素//iterator.next();//NoSuchElementException,再次下一个会报这个异常//4.如果希望再次遍历,需要重置我们的迭代器iterator = col.iterator();}
      }
      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;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}@Overridepublic String toString() {return "BooK{" +"name='" + name + '\\'' +", author='" + author + '\\'' +", price=" + price +'}';}
      }
      

      用迭代器遍历元素

  6. Collection接口遍历对象方式2-for循环增强

    1. 增强for循环,可以替代iterator迭代器,特点:增强for就是简化版的iterator本质一样。只能用于遍历集合或数组

    2. package com.jshedu.collection;import java.util.ArrayList;
      import java.util.Collection;/* @author Mr.jia* @version 1.0*/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("小李飞刀","古龙",12.1));col.add(new BooK("红楼梦","曹雪芹",9.1));//1.增强for循环,在集合使用//2.增强for底层仍然是迭代器for (Object book:col//快捷键大写I) {System.out.println("book="+book);}//增强for,也可以直接在数组中使用int[] arr={1,3,4,5,56,};for (int i:arr) {System.out.println("i="+i);}}
      }

      增强for直接把数组名或集合名传进去就能把单个元素输出

  7. List接口和方法

    1. package com.jshedu.List_;import java.util.ArrayList;
      import java.util.List;/* @author Mr.jia* @version 1.0*/public class List_ {@SuppressWarnings({"all"})public static void main(String[] args) {//1.List集合类中元素有序(即添加顺序和取出顺序一致),且可重复List list = new ArrayList();list.add("jack");list.add("tom");list.add("Rose");list.add("aili");list.add(213);System.out.println("list="+list);//list=[jack, tom, Rose, aili, 213]//2.List集合中的每个元素都有其对应的顺序索引,即支持索引//  索引从0开始System.out.println(list.get(3));//aili}
      }
      

      有序,可重复

    2. List方法

      package com.jshedu.List_;import java.util.ArrayList;
      import java.util.List;/* @author 韩顺平* @version 1.0*/
      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);//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);//list=[张三丰, jack, tom, 韩顺平, 贾宝玉]
      //        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);//list=[张三丰, jack, tom, 韩顺平, 贾宝玉, 韩顺平]System.out.println(list.lastIndexOf("韩顺平"));//5
      //        Object remove(int index):移除指定index位置的元素,并返回此元素list.remove(0);System.out.println("list=" + list);//list=[jack, tom, 韩顺平, 贾宝玉, 韩顺平]
      //        Object set(int index, Object ele):设置指定index位置的元素为ele , 相当于是替换.list.set(1, "玛丽");System.out.println("list=" + list);//list=[jack, 玛丽, 韩顺平, 贾宝玉, 韩顺平]
      //        List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合// 注意返回的子集合 fromIndex <= subList < toIndexList returnlist = list.subList(0, 2);System.out.println("returnlist=" + returnlist);//returnlist=[jack, 玛丽]}
      }
      
  8. List的三种遍历方式【List 接口的实现子类ArrayList,LinkedList,Vector】

    1. package com.jshedu.List_;import java.util.*;/* @author 韩顺平* @version 1.0*/
      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. 增强forfor (Object o : list) {System.out.println("o=" + o);}System.out.println("=====普通for====");//3. 使用普通forfor (int i = 0; i < list.size(); i++) {System.out.println("对象=" + list.get(i));}}
      }
      

      迭代器,增强for,普通for

    2. 例题

      package com.jshedu.List_;import java.util.*;/* @author Mr.jia* @version 1.0*/
      /*
      名称:红楼梦		价格:100.0		作者:曹雪芹
      名称:三国演义		价格:10.1		作者:罗贯中
      名称:小李飞刀		价格:12.1		作者:古龙
      名称:红楼梦		价格:9.1		作者:曹雪芹
      定制排序后======
      名称:红楼梦		价格:9.1		作者:曹雪芹
      名称:三国演义		价格:10.1		作者:罗贯中
      名称:小李飞刀		价格:12.1		作者:古龙
      名称:红楼梦		价格:100.0		作者:曹雪芹*/
      public class Homework03 {@SuppressWarnings({"all"})public static void main(String[] args) {//List arrayList = new ArrayList();//LinkedList arrayList = new LinkedList();Vector arrayList = new Vector();//三种集合实现都okarrayList.add(new Book("红楼梦","曹雪芹",100));arrayList.add(new Book("三国演义","罗贯中",10.1));arrayList.add(new Book("小李飞刀","古龙",12.1));arrayList.add(new Book("红楼梦","曹雪芹",9.1));System.out.println();//迭代器Iterator iterator = arrayList.iterator();while (iterator.hasNext()) {Object next =  iterator.next();System.out.println(next);}//这里用的定制排序bubble(arrayList, new Comparator() {//匿名内部类@Overridepublic int compare(Object o1, Object o2) {Book i1 = (Book) o1;Book i2 = (Book) o2;return (int)(i1.getPrice()-i2.getPrice()  );//更改i1-i2变化排序顺序}});System.out.println("定制排序后======");iterator = arrayList.iterator();//迭代器重置while (iterator.hasNext()) {Object next =  iterator.next();System.out.println(next.toString());}
      //        for (Object o :) {
      //
      //        }}//冒泡排序public static void bubble(List list, Comparator c){Object temp;for (int i = 0; i < list.size()-1; i++) {//外层循环次数for (int j = 0; j < list.size()-1-i ; j++) {if(c.compare(list.get(j),list.get(j+1))>0){//用List方法进行位置交换temp = list.get(j);list.set(j,list.get(j+1));list.set(j+1,temp);}}}}}
      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;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public double getPrice() {return price;}public void setPrice(double price) {this.price = price;}@Overridepublic String toString() {return "名称:"+getName()+"\\t\\t"+"价格:"+getPrice()+"\\t\\t"+"作者:"+getAuthor();}
      }
      

      集合的运用匿名内部类,compare方法重写,List用方法位置交换

  9. ArrayList注意事项

    1. ArrayList可以加入null,并且多个

    2. ArrayList是由数组来实现数据存储的

    3. ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高),在多线程情况下,不建议使用ArrayList。

  10. ArrayList底层结构和源码分析

    1. ArrayList中维护了一个Object类型【这就是集合为什么可以存储任意类型的数据】的数组elementData【】。transient Object[] elementData;transient表示瞬间,短暂的,表示该属性不会被序列话。

    2. 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。【也就是10+10/2=15,为什么这样写,因为底层扩容机制就是按这个算法来的grow()】

      1.  代码执行流程,elementData==空【大写的一串英文】

         minCapacity表示的是需要几个空间,

         

    3. 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData 为1.5倍。【在你提供的任意数的1.5倍,】