集合的使用和List

集合

第一节:概念
  1. 概念
集合:就是一个存储数据的容器。 
集合与数组一样,也是一个容器,与数组的区别: 
1 数组长度固定,集合的长度不固定。 
2 数组可以存储基本类型和引用类型,集合中存储的元素类型只能是引用类型。
  1. 集合框架的介绍(Collection)
    在这里插入图片描述

  2. Map集合的框架结构

    在这里插入图片描述

  3. 集合和数组相比:

    相同点:都是数据的容器,在一个数组或集合中可以存储多个数据

    不同点:

    1. 元素:数组中的元素都只能是相同的类型,集合中的元素类型可以不同

      ​ 数组中的可以存储基本类型和引用类型,集合只能存储引用类型

    2. 长度:数组的长度是固定的,一旦初始化长度后就不能改变。

      ​ 集合的长度可以修改,可以删除元素和添加元素

第二节:Collection接口

Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些

collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。

List派系:可以重复、有序

Set派系:不能重复、无序

常用方法:

方法名描述
boolean add(E e)确保此 collection 包含指定的元素(可选操作)。
boolean addAll(Collection<? extends E> c)将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
void clear()移除此 collection 中的所有元素(可选操作)。
boolean contains(Object o)如果此 collection 包含指定的元素,则返回true。
boolean containsAll(Collection<?> c)如果此 collection 包含指定 collection 中的所有元素,则返回 true。
boolean equals(Object o)比较此 collection 与指定对象是否相等。
boolean isEmpty()如果此 collection 不包含元素,则返回true。
iterator()返回在此 collection 的元素上进行迭代的迭代器。
boolean remove(Object o)从此 collection 中移除指定元素的单个实例,如果存在的话(可选作)。
boolean removeAll(Collection<?> c)移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
int size()返回此 collection 中的元素数。
Object[] toArray()返回包含此 collection 中所有元素的数组。
第三节:迭代器Iterator

迭代器相当于一个游标,最初获取迭代器时,迭代器的位置在所有元素的前面,每迭代一个元素,迭代器向后移动一 个位置

原理:

在这里插入图片描述

使用:

方法名描述
hasNext()判断迭代器是否存在下一个元素可以迭代器
next()迭代器迭代下一个元素
remove()从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

在这里插入图片描述

第四节:List接口
方法名描述
add(int index, E element)在列表的指定位置插入指定元素(可选操作)。
addAll(int index, Collection<? extends E> c)将指定 collection 中的所有元素都插入到列表中的指定位置
containsAll(Collection<?> c)如果列表包含指定 collection 的所有元素,则返回true。
get(int index)返回列表中指定位置的元素。
indexOf(Object o)返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
lastIndexOf(Object o)返回此列表中最后出现的指定元素的索引;如果列表不包含此元素,则返回 -1。
listIterator()返回此列表元素的列表迭代器(按适当顺序)。
remove(int index)移除列表中指定位置的元素(可选操作)。
set(int index, E element)用指定元素替换列表中指定位置的元素(可选操作)。
subList(int fromIndex, int toIndex)返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

list接口存储的特点:

1 相对有序存储,可以存储相同元素(不排重),可以通过下标访问集合元素

2 List接口中可以使用独有的迭代器ListIterator,具有反向遍历的功能

第五节:ArrayList实现类
ArrayList类是List接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括null在内的所有元素。 

存储特点: 

相对有序存储,可以存储相同元素(不排重),可以通过下标访问集合元素,通过数组实现的集合 

存储结构:数组 

代码实现:

public class ArrayListDemo {
	public static void main(String[] args) { 
        //创建一个ArrayList集合 
        ArrayList<String> list = new ArrayList<>();//构造方法中的泛型可以省略 
        list.add("zhangsan");//向集合中添加元素 
        list.add("lisi"); 
        list.add("wangwu"); 
        System.out.println(list.isEmpty());//判断list集合是否为空集合 
        System.out.println(list.size());//查看集合中元素的个数 
        System.out.println(list.get(1));//获取集合中下标为1的元素 
        System.out.println(list.set(1,"zhaoliu"));//修改集合中下标为1的元素 
        System.out.println(list.contains("wangwu"));//查看"wangwu"是否是集合中的元素 
        list.remove("wangwu");//删除集合中"wangwu"元素 
        list.remove(1);//删除集合中下标为1的元素
        //for循环遍历集合
		for(int i=0; i<list.size(); i++){ 	
            System.out.println(list.get(i)); 
        }
        //使用Iterator迭代器遍历 
        Iterator<String> it = list.iterator();
        //获取迭代器 
        while(it.hasNext()){ 
            System.out.println(it.next()); 
        }
        //使用ListIterator迭代器遍历 
        ListIterator<String> lit = list.listIterator(); 
        while(lit.hasNext()){ 
            System.out.println(lit.next()); 
        }
        //反向遍历 
        while(lit.hasPrevious()){ 
            System.out.println(lit.previous()); 
        } 
    } 
}
第六节:LinkedList类
LinkedList类是List接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括null)。 
存储结构:  双向链表 
存储特点: 相对有序存储,可以存储相同元素(不排重),可以通过下标访问集合元素,通过			
        链表实现的集合

使用:

public class Demo5 { 
    public static void main(String[] args) { 
        //创建集合 
        LinkedList<String> linkedList=new LinkedList<>(); 
        //1添加元素 
        linkedList.add("苹果"); 
        linkedList.add("葡萄"); 
        linkedList.add("西瓜"); 
        linkedList.add("芒果"); 
        linkedList.add("桃子"); 
        System.out.println("元素个数:"+linkedList.size()); 
        System.out.println("打印:"+linkedList.toString()); 
        //2删除 
        // linkedList.remove(0); 
        // System.out.println("删除之后:"+linkedList.toString()); 
        //3遍历 
        //3.1for 
        //3.2foreach 
        //3.3迭代器 
        System.out.println("-----------迭代器-----------"); 
        Iterator<String> it = linkedList.iterator(); 
        while(it.hasNext()) {
            System.out.println(it.next()); 
        }
        //3.4 列表迭代器 
        System.out.println("-----------列表迭代器-----------"); 
        ListIterator<String> lit = linkedList.listIterator(); 
        while(lit.hasNext()) { 
            System.out.println(lit.next()); 
        }
        //3.5降序迭代器 
        System.out.println("-----------降序迭代器-----------"); 
        Iterator<String> dit = linkedList.descendingIterator(); 
        while(dit.hasNext()) { 
            System.out.println(dit.next()); 
        }
        //4判断 
        System.out.println("isEmpty:"+linkedList.isEmpty()); 
        System.out.println("苹果:"+linkedList.contains("苹果")); 
        //5查找位置 
        System.out.println("桃子的位置:"+linkedList.indexOf("桃子")); 
    } 
}
ArrayList和LinkedList的总结
ArrayList存储结构是数组,LinkedList存储结构是双向链表。
ArrayList集合适用在对元素查询、遍历操作,不适合插入和删除。 
LinkedList集合适用在对元素插入和删除操作,不适合遍历和查找。
第七节:Vector

Vector类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是Vector 的大小可以根据需要增大或缩小,以适应创建 Vector后进行添加或移除项的操作。

public static void main(String[] args) { 
    //创建集合 
    Vector<String> vector=new Vector<>(); 
    //1添加元素 
    vector.add("xxx"); 
    vector.add("yyy"); 
    vector.add("zzz"); 
    System.out.println(vector.toString()); 
    //2删除 
    // vector.remove(0); 
    // System.out.println("删除之后:"+vector.toString()); 
    //3遍历 //3.1for //3.2foreach //3.3迭代器 //3.4枚举器 
    Enumeration<String> elements = vector.elements(); 
    while(elements.hasMoreElements()) {
        System.out.println(elements.nextElement()); 
    }
ArrayList与LinkedList、Vector三种实现类存储的比较
a.功能基本相同 
b.底层存储结构:ArrayList是数组,LinkedList是链表,Vector是数组 
c.Vector是一个古老的集合,从JDK1.0开始就有了,Vector存在一些方法名比较长的方法,	xxxElement 
d.Vector是线程安全的,效率低,ArrayList是线程不安全的,效率高,推荐使用		 	ArrayList【Collections工 具类中有相应的方法可以将ArrayList改为线程安全的】 
e.ArrayList查找遍历比较快,LinkedList插入删除比较快
  • ArrayList :主要实现类 。语法结构: ArrayList list = new ArrayList();
    特点:① 数组结构实现,查询快,增删慢(增删一个元素,后面的元素都要移动位置)
    ② JDK1.2版本,运行效率快、效率不安全(对比另一个实现类Vector的add方法讲解)
  • Vector : 特点:①数据结构实现,查询快,增删慢(方法和ArrayList类似);
    ②JDK1.0版本,运行效率慢、线程安全(主要区别在于一个关键字synchronized,可举例说明线程安全和效率的关系)
  • LinkedList: 链表结构实现,增删快,查询慢。通过图示对比链表和顺序表的区别
  • [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QTahkiiN-1588649158308)(图片\linkedlist.png)]
list的扩容

在这里插入图片描述

 new  ArrayList()  
          =>  Object[] elementData  = {};
		初始长度为 0
		当第一次 调用 add方法时, 把elementData数组长度初始为10  
		当elementData不足于存储数据时 ,会新建一个数组,长度为原来的1.5倍
		原来的数组长度 int oldCapacity = elementData.length;
        新的长度  int newCapacity = oldCapacity + (oldCapacity >> 1);

1.list的底层数据结构是 数组!(有序连续存储,有下标,可重复,长度固定)
2.看源码得知 Object[]  数组名  elementData, 长度为0     elementData ={};
3.当增加元素调用add 方法时。会初始 elementData 长度为 10。
4.当list集合中元素个数大于10时,会调用grow方法实现扩容。
5.在原有的数组长度+原来的数组长度的0.5倍   换句话说 扩容后的数组长度为原来 的1.5倍
   源码:int newCapacity = oldCapacity + (oldCapacity >> 1);	
6. 最后 通过 Arrays.copyof方法  复制原有数组中的元素到新数组中,长度是原来的1.5倍。
总结:list 的存储数据结构 可以说是动态数组!
第八节:泛型
  • 概念: 参数化类型、类型安全的集合,强制集合元素的类型必须一致。
  • 特点:
    • 编译时即可检查,而非运行时抛出异常
    • 访问时,不必类型转换(拆箱)
    • 不同泛型之间引用不能相互赋值,泛型不存在多态。

高级应用:

实例泛型接口泛型静态泛型

实例泛型 举例:
class MyClass<E>{//此时的E就是泛型的一个占位符,源码中常见的有 E T K V 等
	//定义一个实例方法,把泛型作为参数传递
	public void m1(E e){
	}
}
实例泛型在创建对象时具体指明泛型的类型 比如:
MyClass<Integer> mc = new MyClass<Integer>();//此时的泛型就指定为整型
mc.m1(123);
//同样可以指定为其它类型
MyClass<Double> mc2 = new MyClass<Double>();
mc2.m1(12.3);
接口泛型 举例:
interface MyInterface<T>{
    void m2(T t);//把泛型类型作参数传递给抽象方法
} 
class MyImplClass implements MyInterface<Byte>{ //在写实现类的时候指明具体的泛型类型
    @Override
	public void m2(Byte t){
	}
}
静态泛型 举例:
 class MyStaticClass{
	public static<E> void method(E e){
       System.out.println(e.getClass());//会打印具体传递过来形参的值
	}
}
//在实际调用静态方法时,把具体类型传递
MyStaticClass.method(123); //class java.lang.Integer
MyStaticClass.method(12.3);//class java.lang.Double
//此时什么类型都可以接收,但在方法内部会有区别

另,可对静态泛型进行约束
 class MyStaticClass{
	public static<E extends Animal & Comparable> void method(E e){
	// 此时能传进来的类型必须满足两个条件即:继承Animal类,并且实现了Comparable接口(可排序),否则编译错误
	}
}
1<? extends T>:表示T类或者T类的子类 2<? super T>:表示T类或者T类的父类 3<?>:表示任意类型
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值