Java中的集合1(Collection接口、List接口、List接口的三种实现类、List接口的集合迭代)

集合

集合的概念

​ 首先, 我们来聊一聊数组, 我们知道, 数组是同一类元素的有序集合, 但是数组却又一个致命的缺点, 那就是数组一旦被定义, 那就无法再对其容量进行改变了, 但是我们的开发或者日常生活中, 经常要存储一些可变的数据集合, 这时数组便不能满足我们的需要, 我们就需要一些能够动态增长长度的容器来保存我们的数据。而我们需要对数据的保存的各种逻辑可能可能是多种多样的,于是就有了各种各样的数据结构。

Java中对于各种数据结构的实现,就是我们用到的集合

集合API

​ Java的集合类(集合API,集合框架)是Java数据结构的实现,是由很多的接口、抽象类、具体类组成的,都位于java.util包中。

集合的体系图如下:
在这里插入图片描述

Collection接口

​ Collection接口–定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式。

​ Set中的数据对象没有顺序且不可以重复(无序,不重复)。

​ List中的数据对象有顺序且可以重复(有序且重复)。

Collection中定义的集合共有方法:

返回值类型方法名功能
booleanadd(Object element)添加元素
booleanaddAll(Collection c)将制定集合的元素添加到此集合中
booleanremove(Object element)删除指定元素
booleanremoveAll(Collection c)删除指定集合 不包含时,删除相交的元素
voidclear()清空集合
intsize()集合内的元素个数
booleanisEmpty()判断集合是否为空
booleancontains(Object element)判断集合中是否包含指定元素
booleancontainsAll(Collection c)判断是否包含某个集合
booleanretainAll(Collection c)求交集,集合数据发生变化返回true,不变返回false
default booleanremoveIf()条件删除

注意:这里有一个需要注意的地方,使用其添加方法添加基本数据类型时会默认调用valueof()方法装箱,因为**集合只能存储引用数据类型。**例如:

import java.util.ArrayList;
import java.util.Collection;

public class CollectionDemo {
    public static void main(String[] args) {
        Collection data = new ArrayList();
        //集合只能存储引用类型
        data.add("hello!");
        //添加基本类型都会将基本类型装箱为引用类型
        data.add(1);//这里添加1会,将1转换为Integer类型
        data.add("World");
        data.remove(1);
        System.out.println(data);
    }
}

代码示例

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

//Collection中的共有的方法
public class Preview1 {
    public static void main(String[] args) {
        Integer [] arr1 = {1,2,3};
        Collection<Integer> arr = new ArrayList<>(20);
        for (int i = 0; i<15;i++){
            arr.add(i);
        }
        /*
          boolean add(Object element);
          boolean addAll(Collection c);
          boolean remove(Object element);
          boolean removeAll(Collection c);删除指定集合  不包含时,删除相交的元素
          void clear();
          int size();
          boolean isEmpty();
          boolean contains(Object element);
          boolean containsAll(Collection c);
          boolean retainAll(Collection c);   求交集,集合数据发生变化返回true,不变返回false
        */
        System.out.println(arr.add(100));//true
        System.out.println(arr);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 100]
        System.out.println(arr.addAll(Arrays.asList(arr1)));
        System.out.println(arr);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 100, 1, 2, 3]
        System.out.println(arr.remove(1));//[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 100, 1, 2, 3]
        System.out.println(arr);
        System.out.println(arr.removeAll(Arrays.asList(arr1)));
        System.out.println(arr);//[0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 100]
        System.out.println(Arrays.toString(arr1));//[1, 2, 3]
//        arr.clear();
//        System.out.println(arr);//[]
        System.out.println(arr.size());//13
        System.out.println(arr.isEmpty());//false
        System.out.println(arr.contains(10));//true
        System.out.println(arr.containsAll(Arrays.asList(arr1)));//true
        System.out.println(arr.retainAll(Arrays.asList(arr1)));//true
        //removeIf() 条件删除
        System.out.println(arr.removeIf(new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) {
                return integer.equals(0);
            }
        }));
        System.out.println(arr);
    }
}

List接口

有序:按照添加顺序排列。

可以有重复元素。

List继承了Collection接口, 有三个实现的类:

​ ArrayList: 数组列表, 数据采用数组方式存储

​ LinkedList: 链表

​ Vector: 数组列表, 添加了同步锁, 线程安全

List接口的常用方法

List接口的方法在它的实现类中都可以使用。(Collection中定义的方法这里都可以使用)

返回值方法名功能
voidadd(Object obj)将Object类型的元素添加到集合末尾
voidadd(int index, Object obj)将Object类型的元素添加到指定位置
voidaddAll(Collection c)给集合添加一个新集合,也可以加上位置
voidremove(int index)删除指定位置的元素
voidremove(Object obj)删除指定元素(集合中第一次出现)
voidremoveAll(Collection c )删除指定集合,不包含时删除相交得的元素
set(int index,Object o)将指定索引的元素替换为指定的元素
get(int index)返回指定索引位置的元素
booleancontains(Object o)判断集合中是否包含指定元素
booleancontainsAll(Collection c)判断集合中是否包含指定集合
intindexOf(Object o)返回指定元素第一次出现的索引值,没有就返回-1
booleanisEmpty()判断集合是否为空
intlastIndexOf(Object)返回元素最后一次出现的索引值
intsize()返回此集合的元素数量
ListsubList(int formIndex,int toIndex)截取指定区间返回一个集合
voidclear( )清空集合

asList, toArray(), toArray(T[] a) 的用法

import java.lang.String;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

public class Preview1 {
    private static Object String;

    public static void main(String[] args) {
        String [] arr = {"1","2","3","4"};
        //asList--->Arrays中的方法,可以将一个数组转化为集合
        Collection<String> list = new ArrayList();
        System.out.println(list.addAll(Arrays.asList(arr)));
        System.out.println(list);

        //toArray()--->返回一个类型为Object[]的包含集合中的所有元素的数组
        Object [] arr1 = list.toArray();
        System.out.println(Arrays.toString(arr1));

        //返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型
        String[] arr2 = list.toArray(new String[list.size()]);
        System.out.println(Arrays.toString(arr2));
    }
}

代码示例

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;

//List接口的常用方法
public class ListDemo {
     public static void main(String[] args) {
         List list = new LinkedList();
         //添加元素---末尾
         list.add("中");
         list.add(1);
         list.add(true);
         System.out.println(list);
         //添加元素到指定位置
         list.add(1,"风");
         //添加一个新集合
         Collection c = new LinkedList();
         c.add(1);
         c.add(2);
         c.add(3);
         list.addAll(c);
         System.out.println(list);
         //添加一个新集合到指定位置
         list.addAll(2,c);
         System.out.println(list);
        //删除指定位置元素
         list.remove(1);
         System.out.println(list);
         //删除指定元素
         list.remove(1);
         System.out.println(list);
         //修改指定位置元素---返回这个位置之前的元素
         System.out.println(list.set(3,"天"));
         //查询指定位置元素
         System.out.println(list.get(3));
         //判断集合送是否包含指定元素
         System.out.println(list.contains("天"));
         //判断是否包含指定集合
         System.out.println(list.containsAll(c));
         //返回元素第一次出现的索引值,没有就返回-1
         System.out.println(list.indexOf("风"));
         //判断集合是否为空
         System.out.println(list.isEmpty());
         //返回元素最后出现一次的索引值
         System.out.println(list.lastIndexOf(3));
         //返回集合中的元素数量
         System.out.println(list.size());
         //截取集合中的指定区间
         System.out.println(list.subList(2,5));
         //清空集合
         list.clear();
     }
}
实现类:ArrayList

​ ArrayList是实现了长度可变的数组, 在内存中分配连续的空间。

​ **优点:**底层数据结构是数组,查询快,增删慢,遍历元素和随机访问元素的效率高。

​ **缺点:**线程不安全。

ArrayList的常用方法(list接口中的方法在ArrayList中都可用):

返回值方法名功能
voidensureCapacity(int minCapacity)自行增加容量,以保证它最少有指定数量的元素
protected voidremoveRange(int f,int e)删除指定区间的元素,需要继承ArrayList才能使用
booleanretainAll(Collection c)仅保留此集合中在包含指定集合的元素
voidtrimToSize()修改当前集合的容量大小为元素个数数量
voidsort(比较器)需要传入一个比较器进行排序

代码示例

import java.util.ArrayList;
import java.util.Comparator;


public class ArrayListDemo extends ArrayList {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        //添加元素---末尾
        list.add("中");
        list.add(1);
        list.add(true);
        System.out.println(list);
        //添加元素到指定位置
        list.add(1, "风");
        //添加一个新集合
        ArrayList c = new ArrayList();
        c.add(1);
        c.add(2);
        c.add(3);
        list.addAll(c);
        System.out.println(list);
        //自行增加容量---让其有最少为指定的容量
        list.ensureCapacity(20);
        //删除指定区间,这是一个受保护权限,需要继承ArrayList才能在子类中调用
        ArrayListDemo list1 = new ArrayListDemo();
                list1.add(0);
                list1.add(1);
                list1.add(2);
                list1.add(3);
                list1.add(4);
                list1.add(5);
        list1.removeRange(1,4);
        System.out.println(list1);
        //仅保留此集合中包含在指定集合中的元素
        list.retainAll(c);
        System.out.println(list);

        //sort 传入一个比较器进行排序
        ArrayList<Integer> list2 = new ArrayList<>();
        list2.add(3);
        list2.add(7);
        list2.add(5);
        list2.add(0);
        list2.add(1);
        list2.sort(new pd());
        System.out.println(list2);
    }
}

class pd implements Comparator<Integer>{

    @Override
    public int compare(Integer o1, Integer o2) {
        return o1-o2;
    }
} 
实现类:LinkedList

​ LinkedList采用链表存储的方式。插入、删除元素时效率较高。

​ 优点:底层数据结构使用的是链表,查询快、增删慢。

​ 缺点:线程不安全。

LinkedList的常用方法和ArrayList的差不多,也都实现了List接口和Collection接口,底层以链表的形式存储

代码示例

import java.util.*;

public class LinkedListDemo extends LinkedList{
    public static void main(String[] args) {
        LinkedList list = new LinkedList();
        //添加元素---末尾
        list.add("中");
        list.add(1);
        list.add(true);
        System.out.println(list);
        //添加元素到指定位置
        list.add(1,"风");
        //添加一个新集合
        Collection c = new LinkedList();
        c.add(1);
        c.add(2);
        c.add(3);
        list.addAll(c);
        System.out.println(list);
        //添加一个新集合到指定位置
        list.addAll(2,c);
        System.out.println(list);
        //删除指定位置元素
        list.remove(1);
        System.out.println(list);
        //删除指定元素
        list.remove(1);
        System.out.println(list);
        //修改指定位置元素---返回这个位置之前的元素
        System.out.println(list.set(3,"天"));
        //查询指定位置元素
        System.out.println(list.get(3));
        //判断集合送是否包含指定元素
        System.out.println(list.contains("天"));
        //判断是否包含指定集合
        System.out.println(list.containsAll(c));
        //返回元素第一次出现的索引值,没有就返回-1
        System.out.println(list.indexOf("风"));
        //判断集合是否为空
        System.out.println(list.isEmpty());
        //返回元素最后出现一次的索引值
        System.out.println(list.lastIndexOf(3));
        //返回集合中的元素数量
        System.out.println(list.size());
        //截取集合中的指定区间
        System.out.println(list.subList(2,5));
        //删除指定区间,这是一个受保护权限,需要继承ArrayList才能在子类中调用
        LinkedListDemo list1 = new LinkedListDemo();
        list1.add(0);
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);
        list1.add(5);
        list1.removeRange(1,4);
        System.out.println(list1);
        //sort 传入一个比较器进行排序
        ArrayList<Integer> list2 = new ArrayList<>();
        list2.add(3);
        list2.add(7);
        list2.add(5);
        list2.add(0);
        list2.add(1);
        list2.sort(new pd());
        System.out.println(list2);
    }
}
class pd implements Comparator<Integer> {

    @Override
    public int compare(Integer o1, Integer o2) {
        return o1-o2;
    }
}
实现类:Vector

​ Vector底层实现就是数组,和ArrayList是一致的,但是Vector添加了同步锁synchronized,保证了线程安全。

效率测试

测试ArrayList和LinkedList的存入和查找效率

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;

//测试ArrayList和LinkedList存,查效率
public class Test1 {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        Date date1 = new Date();
        for (int i = 0; i < 10000; i++) {
            list.add("a");
        }
        for (int i = 0; i < 90000; i++) {
            list.add(2500,"a");
        }
        Date date2 = new Date();
        System.out.println("ArrayList存10万次的时间:"+(date2.getTime()-date1.getTime()));
        //        ArrayList存10万次的时间:521ms
        Date date3 = new Date();
        for (int i = 0; i < 100000; i++) {
            list.get(2500);
        }
        Date date4 = new Date();
        System.out.println("ArrayList查10万次的时间:"+(date4.getTime()-date3.getTime()));
        //ArrayList查10万次的时间:0ms

        LinkedList list1 = new LinkedList();
        Date date5 = new Date();
        for (int i = 0; i < 10000; i++) {
            list1.add("a");
        }
        for (int i = 0; i < 90000; i++) {
            list1.add(2500,"a");
        }
        Date date6 = new Date();
        System.out.println("LinkedList存10万次的时间:"+(date6.getTime()-date5.getTime()));
        //LinkedList存10万次的时间:399ms
        Date date7 = new Date();
        for (int i = 0; i < 100000; i++) {
            list1.get(2500);
        }
        Date date8 = new Date();
        System.out.println("LinkedList查10万次的时间:"+(date8.getTime()-date7.getTime()));
        //LinkedList查10万次的时间:401ms
    }
}

List接口的迭代

for循环

​ 语法格式:for(int i;i < list.size() ; i++){…}

注意: for循环有一个缺陷,就是在删除元素的时候,集合的长度会变小,但是索引 i 的值却在不断变大,这就会出现删不尽的情况,因此我们总是需要做一些小小的处理,请看代码。

代码示例

import java.util.ArrayList;

//遍历数组--for循环
public class ForDemo {
    public static void main(String[] args) {
        ArrayList<String> arr = new ArrayList<>();
        arr.add("a");
        arr.add("s");
        arr.add("d");
        arr.add("e");
        arr.add("s");
        System.out.println(arr);

        for (int i = 0; i < arr.size(); i++) {
            System.out.println(arr.get(i));
        }

        //删除元素后,集合的长度也发生了变化,但是索引 i 的值一直在变大,会出现删不尽的情况
        for (int i = 0; i < arr.size(); i++) {
            arr.remove(i);
            //使用 i-- 将i的值不断变小,等于说每一次都在删除敌意个数
            i--;
        }
        System.out.println(arr);//[s, e]
    }

增强for循环

​ 语法格式:for(Object obj:list){System. out. println(obj);}

​ **注意:**增强for循环,不允许在遍历的时候对元素进行操作,否则会抛出异常,但是我们可以进行一次操作,比如删除一个元素后立刻break,趁着jvm还没反应过来抛出异常时,我们就跳出去。

代码示例

import java.util.ArrayList;

//迭代---增强for循环
public class ForeachDemo {
    public static void main(String[] args) {
        ArrayList<String> arr = new ArrayList<>();
        arr.add("a");
        arr.add("s");
        arr.add("d");
        arr.add("e");
        arr.add("s");
        System.out.println(arr);

        for (String s: arr) {
            System.out.println(s);
        }
        //增强for循环,不允许遍历时对元素进行操作,否则会报错:ConcurrentModificationException
        //但是可以进行一次操作,比如删除已次元素后,趁着异常还没抛出时立刻跳出
        for (String s: arr) {
            arr.remove(s);
            break;
        }
        System.out.println(arr);//[s, d, e, s]
    }
}
迭代器–iterator

​ 这是Collection接口中提供的操作,直接上代码:

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Preview2 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add("e");

         Iterator<String> iterator = arr.iterator();
            //hasNext() 检测迭代器中是否还有元素
            while(iterator.hasNext()){
            //每次都从arr中拿出一个元素
                String s = iterator.next();
                if (s.equals("c")){
            //这里不能使用原本的集合对象,因为迭代器中不能直接调用集合对象,需要使用iterator作为中间人
                    iterator.remove();
                }
            }
        System.out.println(arr);
    }
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值