Java19--集合1(Collection+List+ArrayList+LinkedList)

1 Collection 接口

1.1 概述

英文名称Collection,是用来存放对象的数据结构。其中长度可变,而且集合中可以存放不同类型的对象。并提供了一组操作成批对象的方法。

数组的缺点:长度是固定不可变的,访问方式单一,插入、删除等操作繁琐。

1.2 集合的继承结构

在这里插入图片描述

Collection接口

-- List接口  : 数据有序,可以重复。

   -- ArrayList子类

   -- LinkedList子类

-- Set接口  : 数据无序,不可以存重复值

   -- HashSet子类

-- Map接口  : 键值对存数据

-- HashMap

Collections工具类

1.3 常用方法

boolean add(E e):添加元素。

boolean addAll(Collection  c):把小集合添加到大集合中 。

boolean contains(Object o) : 如果此 collection 包含指定的元素,则返回 true。

boolean isEmpty() :如果此 collection 没有元素,则返回 true。

Iterator<E> iterator():返回在此 collection 的元素上进行迭代的迭代器。

boolean remove(Object o) :从此 collection 中移除指定元素的单个实例。

int size() :返回此 collection 中的元素数。

Objec[] toArray():返回对象数组

1.4 练习1:测试常用方法

package seday11;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;

public class Test_301_Collection {

       public static void main(String[] args) {

              Collection c = new ArrayList();//接口无法直接创建对象

              c.add("hello");//添加元素

              c.add("java");//添加元素

              c.add("~");//添加元素

              c.add(10);//jdk5后有自动装箱功能,相当于把10包装Integer.valueOf(10)

              System.out.println(c.remove("~"));//移除元素

              System.out.println(c.contains("a"));//判断包含关系

              System.out.println(c.size());//集合的长度

              System.out.println(c);

             

              //for遍历集合

              for(int i =0 ;i<c.size();i++) {

                     System.out.println(c.toArray()[i]);

              }

              //iterator迭代器遍历

              Iterator it = c.iterator();//对 collection 进行迭代的迭代器

              while (it.hasNext()) {//如果仍有元素,则返回 true

                     System.out.println(it.next());//返回迭代获取到的下一个元素

              }   } }

2 List接口

2.1 概述

有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

2.2 特点

1、 数据有序

2、 允许存放重复元素

3、 元素都有索引

2.3 常用方法

ListIterator<E> listIterator()

          返回此列表元素的列表迭代器(按适当顺序)。

 ListIterator<E> listIterator(int index)

          返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。

 void add(int index, E element)

          在列表的指定位置插入指定元素(可选操作)。

 boolean addAll(int index, Collection<? extends E> c)

          将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。

 List<E> subList(int fromIndex, int toIndex)

     返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

E get(int index)

          返回列表中指定位置的元素。  

int indexOf(Object o)

          返回此列表中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。

2.4 练习1:测试常用方法

创建day12工程

创建cn.tedu.list包

创建Test1_List.java

package cn.tedu.list;

 

import java.util.ArrayList;

import java.util.Iterator;

import java.util.List;

import java.util.ListIterator;

 

//这类用来测试List接口的常用方法

public class Test1_List {

 

    public static void main(String[] args) {

       //1、创建List对象

       //特点1:List集合元素都有索引,可以根据索引直接定位元素

       List list = new ArrayList();

      

       //2、常用方法

       list.add(111);

       list.add(222);

       list.add(333);

       list.add(444);

       list.add('a');

       list.add("abc");

      

       list.add(3,666);//在3的索引处添加指定元素

 

       //特点2:元素有序, 怎么存就怎么放

       System.out.println(list);//[111, 222, 333, 666, 444, a, abc]

      

       Object obj = list.get(4);//get(m)-m是索引值,获取指定索引位置的元素

       System.out.println(obj);

      

      

       //3、迭代/遍历集合中的元素

       //使用Collection接口提供的iterator()

       Iterator it = list.iterator();

       while(it.hasNext()) {//判断集合里有没有下个元素

           Object o = it.next();

//         System.out.println(o);

       }
     

       //使用List接口提供的listIterator()

       //interfaceListIterator extends Iterator

       //区别:可以使用父接口的功能,同时拥有自己的特有功能,不仅顺序向后迭代还可以逆向迭代

       ListIterator it2 = list.listIterator();

       while(it2.hasNext()) {

           Object o = it2.next();

//         System.out.println(o);

       }

      
       System.out.println();

      
       List list2 = list.subList(1, 3);//subList(m,n)-m是开始索引,n是结束索引,其中含头不含尾类似于String.subString(m,n)

       System.out.println(list2);


    }
}

3 ArrayList

3.1 概述

  1. 存在于java.util包中。
    
  2. 内部用数组存放数据,封装了数组的操作,每个对象都有下标。
    
  3. 内部数组默认初始容量是10。如果不够会以1.5倍容量增长。
    
  4. 查询快,增删数据效率会降低。
    

在这里插入图片描述

在这里插入图片描述

3.2 创建对象

new ArrayList():初始容量是10

3.3 练习1:测试常用方法

常用API,包括下标遍历,迭代器遍历

package seday11;

import java.util.ArrayList;

public class Test3_AL {

       public static void main(String[] args) {

              ArrayList list = new ArrayList();

              list.add("aaa");//存入数据

              list.add("123");

              list.add("ccc");

              list.add("ddd");

              System.out.println(list);//list中内容

              System.out.println(list.size());//集合长度

              System.out.println(list.get(1));//根据下标获取元素

                    

              System.out.println();

              System.out.println(list.remove(2));//移除下标对应的元素

              System.out.println(list);

                    

                     //下标遍历

                     for (int i = 0; i < list.size(); i++) {

                            System.out.print(list.get(i));

                     }

 

       //Iterator迭代遍历,封装了下标

                     Iterator<String> it = list.iterator();

                     while (it.hasNext()) {//如果有数据

                            String s = it.next();//一个一个向后遍历

                            System.out.println(s);

                     }     

              }

}

4 LinkedList

4.1 概述

双向链表,两端效率高。底层就是数组和链表实现的。
在这里插入图片描述

4.2 常用方法

add()

get()

size()

remove(i)

remove(数据)

iterator()

addFirst()  addLast()

getFirst()  getLast()

removeFirst()  removeLast()

4.3 练习1:测试迭代器遍历

双向链表:下标遍历效率低,迭代器遍历效率高

package dd;

 

import java.util.ArrayList;

import java.util.Iterator;

import java.util.LinkedList;

 

public class tt {

       public static void main(String[] args) throws Exception {

              LinkedList ll = new LinkedList ();

              for (int i = 0; i < 100000; i++) {

                     ll.add(100);

              }

              f1(ll);

              f2(ll);

       }

 

       private static void f2(LinkedList<Integer> ll) {

              long t = System.currentTimeMillis();

              Iterator it = ll.iterator();

              while(it.hasNext()) {

                     it.next();

              }

              t = System.currentTimeMillis()-t;

              System.out.println("=====iterator========="+t);//16

       }

 

       private static void f1(LinkedList<Integer> ll) {

              long t = System.currentTimeMillis();

              for (int i = 0; i < ll.size(); i++) {

                     ll.get(i);

              }

              long t1 = System.currentTimeMillis();

              System.out.println("~~~~for~~~~~~~"+(t1-t));//9078

       }

}

5 拓展

5.1 ArrayList扩容

ArrayList相当于在没指定initialCapacity时就是会使用延迟分配对象数组空间,当第一次插入元素时才分配10(默认)个对象空间。假如有20个数据需要添加,那么会分别在第一次的时候,将ArrayList的容量变为10 (如下图一);之后扩容会按照1.5倍增长。也就是当添加第11个数据的时候,Arraylist继续扩容变为10*1.5=15(如下图二);当添加第16个数据时,继续扩容变为15 * 1.5 =22个

ArrayList没有对外暴露其容量个数,查看源码我们可以知道,实际其值存放在elementData对象数组中,那我们只需拿到这个数组的长度,观察其值变化了几次就知道其扩容了多少次。怎么获取呢?只能用反射技术了。
在这里插入图片描述

5.2 HashMap扩容

成长因子:

static final float DEFAULT_LOAD_FACTOR = 0.75f;

前面的讲述已经发现,当你空间只有仅仅为10的时候是很容易造成2个对象的hashcode 所对应的地址是一个位置的情况。这样就造成 2个 对象会形成散列桶(链表)。这时就有一个加载因子的参数,值默认为0.75 ,如果你hashmap的 空间有 100那么当你插入了75个元素的时候 hashmap就需要扩容了,不然的话会形成很长的散列桶结构,对于查询和插入都会增加时间,因为它要一个一个的equals比较。但又不能让加载因子很小,如0.01,这样显然是不合适的,频繁扩容会大大消耗你的内存。这时就存在着一个平衡,jdk中默认是0.75,当然负载因子可以根据自己的实际情况进行调整。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值