Java基础学习笔记11——集合(Collection)接口

目录

1、Collection集合

1.1、Collection集合概述

1.2、创建Collection集合的对象

1.3、Collection集合常用方法

1.4、Collection集合的遍历

1.5、Collection的子接口——List集合

1.5.1、List集合的特点

1.5.2、List集合的特有方法

1.5.3、迭代器Iterator引发并发修改异常(ConcurrentModificationException)

1.5.4、ListIterator(列表迭代器)

1.5.5、增强for循环

1.5.6、List集合的实现类(子类)

1.6、Collection的子接口——Set集合

1.6.1、Set集合的特点

1.6.2、哈希值

1.6.3、哈希表

1.6.4、Set集合的实现类(子类)

2、Map集合

2.1、Map集合概述

2.2、Map集合的常用功能

2.3、Map集合的获取功能

2.4、Map集合的遍历

2.4.1、遍历方式1

2.4.2、遍历方式2

2.5、Map集合的实现类(子类)

3、Collections类

3.1、Collection类概述

3.2、Collections类的常用方法


集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以发生改变。

集合类的体系结构:

集合类的体系结构

1、Collection集合

Collection接口在java.util包下,使用前需要导包。

1.1、Collection集合概述

  • 是单列集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素;
  • JDK不提供此接口的任何直接实现,它提供更具体地子接口(如Set和List)实现。

1.2、创建Collection集合的对象

  • 多态的方式;
  • 具体的实现类(如ArrayList等)。

1.3、Collection集合常用方法

方法名描述
boolean add(E e)添加元素
boolean remove(Object o)从集合中移除指定的元素
void clear()清空集合中的元素
boolean contains(Object o)判断集合中是否存在指定的元素
boolean inEmpty()判断集合是否为空
int size()集合的长度,也就是集合中元素的个数

1.4、Collection集合的遍历

Iterator:迭代器,集合的专用遍历方式

  • Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到;
  • 迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的。

Iterator中的常用方法:

  • E next():返回迭代中的下一个元素;
  • boolean hasNext():如果迭代具有更多元素,则返回true。

Iterator不允许在遍历过程中修改集合。

代码演示:

package IterPackage;

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

public class Test {
    public static void main(String[] args) {
        //创建集合对象
        Collection<String> c = new ArrayList<String>();

        //添加元素
        c.add("Hello");
        c.add("World");
        c.add("Java");

        //遍历集合
        //Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到;
        Iterator<String> it = c.iterator(); //多态,返回的是迭代器接口的实现类对象
        //boolean hasNext():如果迭代具有更多元素,则返回true。
        while(it.hasNext()){
            System.out.println(it.next()); //E next():返回迭代中的下一个元素;
        }
    }


结果:
Hello
World
Java

1.5、Collection的子接口——List集合

List接口在java.util包下,使用前需要导包。List接口继承自Collection接口。

  • List是有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素;
  • 与集合不同,列表通常允许重复的元素。

1.5.1、List集合的特点

  • 有序:存储和取出的元素顺序一致;
  • 可重复:存储的元素可以重复。

1.5.2、List集合的特有方法

方法名描述
void add(int index, E element)在此集合中的指定位置插入指定的元素
E remove(int index)删除指定索引处的元素,返回被删除的元素
E set(int index, E element)修改指定索引处的元素,返回被修改的元素
E get(int index)返回指定索引处的元素

1.5.3、迭代器Iterator引发并发修改异常(ConcurrentModificationException)

产生原因:Iterator迭代器遍历的过程中,通过集合对象修改了集合中元素的长度,造成了迭代器获取元素中判断预期修改值和实际修改值不一致。

解决方案:用for循环遍历,然后用集合对象做对应的操作即可。

1.5.4、ListIterator(列表迭代器)

ListIterator(迭代器Iterator的子类)通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器。

ListIterator允许程序员沿任一方向遍历列表,在迭代期间修改列表,并获取列表中迭代器的当前位置。

ListIterator中的常用方法:

  • E next():返回迭代中的下一个元素;
  • E previous():返回列表中的上一个元素;
  • boolean hasNext():如果迭代具有更多元素,则返回true;
  • boolean hasPrevious():如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true;
  • void add(E, e):将指定的元素插入列表。

1.5.5、增强for循环

增强for:简化数组和Collection集合的遍历。

  • 实现Iterable接口的类允许其对象成为增强型for语句的目标;
  • 它是JDK5之后出现的,其内部原理是一个Iterator迭代器。

增强for的格式:

//格式
for(元素数据类型 变量名:数组或者Collection集合){ //内部原理是一个Iterator迭代器
    //在此处使用变量即可,该变量就是元素
}

//范例
int[] arr = {1, 2, 3, 4, 5};
for(int i:arr){
    System.out.println(i);
}

1.5.6、List集合的实现类(子类)

List集合的常用子类:ArrayList, LinkedList 。

  • ArrayList的底层结构是数组,查询快,增删慢。
  • LinkedList的底层数据结构是链表,查询慢,增删快。

二者的用法基本相同。

1、ArrayList类

ArrayList在java.util包下,使用前需要导包。ArrayList的底层结构是数组,查询快,增删慢。

ArrayList<E>:

  • 可调整大小的数组实现;
  • <E>:是一种特殊的数据类型,泛型。

在出现E的地方我们使用数据类型替换即可。举例:ArrayList<String>。

1)ArrayList集合的构造方法和添加方法

方法名说明
public ArrayList()创建一个空的集合对象
public boolean add(E e)将指定的元素追加到此集合的末尾
public void add(int index, E element)在此集合中的指定位置插入指定的元素

代码演示:

package myPackage;

import java.util.ArrayList;

public class TestArrayList {
    public static void main(String[] args) {
        //创建一个集合对象
        ArrayList<String> array = new ArrayList<>();
        //ArrayList<String> arrat = new ArrayList<String>(); //第二种方式

        //添加元素到集合末尾。public boolean add(E e):将指定的元素追加到此集合的末尾
        System.out.println(array.add("Hello"));
        array.add("World");
        System.out.println("array:"+array);

        //在集合的指定位置添加元素。public void add(int index, E element):在此集合中的指定位置插入指定的元素
        array.add(1,"Java");
        System.out.println("array:"+array);
    }


结果:
true
array:[Hello, World]
array:[Hello, Java, World]

2)ArrayList集合的常用方法

方法名说明
public boolean remove(Object o)删除指定的元素,返回删除是否成功
public E remove(int index)删除指定索引处的元素,返回被删除的元素
public E set(int index, E element)修改指定索引处的元素,返回被修改的元素
public E get(int index)返回指定索引处的元素
public int size()返回集合中的元素的个数

代码演示:

package myPackage;

import java.util.ArrayList;

public class TestArrayList {
    public static void main(String[] args) {
        //创建一个集合对象
        ArrayList<String> array = new ArrayList<>();

        //添加元素
        array.add("Hello");
        array.add("World");
        array.add("Java");
        array.add("OK");
        System.out.println("原集合:" + array);

        //public boolean remove(Object o):删除指定的元素,返回删除是否成功
        System.out.println("删除World:" + array.remove("World") + "," + "结果为"+array);
        System.out.println("删除dsad:" + array.remove("dsad") + "," + "结果为"+array);

        //public E remove(int index):删除指定索引处的元素,返回被删除的元素
        System.out.println("删除索引为1的元素:" + "删除了" + array.remove(1) + "," + "结果为"+array);

        //public E set(int index, E element):修改指定索引处的元素,返回被修改的元素
        System.out.println("修改索引为0的元素为change:" + "修改了" + array.set(0,"change") + "," + "结果为"+array);

        //public E get(int index):返回指定索引处的元素
        System.out.println("返回索引为0的元素:" + "返回了了" + array.get(0) + "," + "结果为"+array);

        //public int size():返回集合中的元素的个数
        System.out.println("集合中元素个数为:" + array.size());
    }
}


结果:
原集合:[Hello, World, Java, OK]
删除World:true,结果为[Hello, Java, OK]
删除dsad:false,结果为[Hello, Java, OK]
删除索引为1的元素:删除了Java,结果为[Hello, OK]
修改索引为0的元素为change:修改了Hello,结果为[change, OK]
返回索引为0的元素:返回了了change,结果为[change, OK]
集合中元素个数为:2

2、LinkedList 类

LinkedList的底层数据结构是链表,查询慢,增删快。用法与ArrayList基本相同。

1)LinkedList集合的特有功能

方法名描述
public void addFirst(E e在该列表开头插入指定的元素
public void addLast(E e)将指定的元素追加到此列表的末尾
public E getFirst()返回此列表中的第一个元素
public E getLast()返回此列表中的最后一个元素
public E removeFirst()从此列表中删除并返回第一个元素
public E removeLast()从此列表中删除并返回最后一个元素

1.6、Collection的子接口——Set集合

1.6.1、Set集合的特点

  • 不包含重复元素;
  • 没有带索引的方法,所以不能使用普通for循环遍历。

1.6.2、哈希值

哈希值是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值。

Object类中有一个方法可以获取对象的哈希值:

//返回对象的哈希码值
public int hashCode();

对象的哈希值特点:

  • 同一个对象多次调用hashCode()方法返回的哈希值是相同的;
  • 默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法(该方法可在元素类中自动生成),可以实现让不同对象的哈希值相同。

1.6.3、哈希表

  • JDK8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组;
  • JDK8以后,在长度比较长的时候,底层实现了优化。

1.6.4、Set集合的实现类(子类)

1、HashSet类

1)HashSet集合的特点:

  • 底层数据结构是哈希表;
  • 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致;
  • 没有带索引的方法,所以不能使用普通for循环遍历(可使用增强for循环);
  • 由于是Set集合,所以是不包含重复元素的集合。

2、LinkedHashSet类

1)LinkedHashSet集合的特点:

  • 哈希表和链表实现的Set接口,具有可预测的迭代次序;
  • 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的;
  • 由哈希表保证元素唯一,也就是说没有重复的元素。

3、TreeSet类(间接实现Set接口)

1)TreeSet集合的特点:

构造方法

描述

TreeSet()

根据其元素的自然排序进行排序

TreeSet(Comparator comparator)

根据指定的比较器进行排序

  • 元素有序,这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法:
  • 没有带索引的方法,所以不能使用普通for循环遍历(可使用迭代器和增强for遍历);
  • 由于是Set集合,所以不包含重复元素。

2)自然排序Comparable的使用:

需求:

  1. 存储学生对象并遍历,创建TreeSet集合使用无参构造方法;
  2. 按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序。

结论:

  1. 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的;
  2. 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法;
  3. 重写方法时,一定要注意排序规则,必须按照要求的主要条件和次要条件来写。

代码实现:

package TSPackage;

public class Student implements Comparable<Student>{
    private String name; //姓名
    private int age; //年龄

    public Student() {
    }

    public Student(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 int compareTo(Student s) {
        //return 0; //该返回值说明新添加的元素是重复的
        //return 1; //按照存储顺序添加元素
        //return -1; //按照存储倒序添加元素

        //按照年龄从小到大排序
        int num = this.age - s.age; //按年龄升序
        //年龄相同时,按照姓名的字母顺序排序
        return num == 0 ? this.name.compareTo(s.name) : num; //String类有compareTo()方法
    }
}
package TSPackage;

import java.util.TreeSet;

public class Test {
    public static void main(String[] args) {
        //创建集合对象
        TreeSet<Student> ts = new TreeSet<Student>();

        //创建学生对象
        Student s1 = new Student("zhangsan",20);
        Student s2 = new Student("lisi",19);
        Student s3 = new Student("wangwu",18);
        Student s4 = new Student("zhaoliu",19);

        Student ss = new Student("zhaoliu",19);

        //把学生添加到集合
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);

        ts.add(ss);

        //遍历集合
        for(Student s : ts){
            System.out.println(s.getName()+","+s.getAge());
        }
    }
}
结果:
wangwu,18
lisi,19
zhaoliu,19
zhangsan,20

3)比较器排序Comparator的使用

需求:

  1. 存储学生对象并遍历,创建TreeSet集合使用带参构造方法;
  2. 按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序。

结论:

  1. 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的;
  2. 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1, T o2)方法;
  3. 重写方法时,一定要注意排序规则,必须要按照要求的主要条件和次要条件来写。

代码实现:

package TSPackage;

public class Student {
    private String name; //姓名
    private int age; //年龄

    public Student() {
    }

    public Student(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;
    }
}
package TSPackage;

import java.util.Comparator;
import java.util.TreeSet;

public class Test {
    public static void main(String[] args) {
        //创建集合对象
        TreeSet<Student> ts = new TreeSet<Student>(new Comparator<Student>() { //匿名内部类
            @Override
            public int compare(Student s1, Student s2) {
                //return 0; //该返回值说明新添加的元素是重复的
                //return 1; //按照存储顺序添加元素
                //return -1; //按照存储倒序添加元素

                //按照年龄从小到大排序
                int num = s1.getAge() - s2.getAge(); //按年龄升序
                //年龄相同时,按照姓名的字母顺序排序
                return num == 0 ? s1.getName().compareTo(s2.getName()) : num; //String类有compareTo()方法
            }
        });

        //创建学生对象
        Student s1 = new Student("zhangsan",20);
        Student s2 = new Student("lisi",19);
        Student s3 = new Student("wangwu",18);
        Student s4 = new Student("zhaoliu",19);

        Student ss = new Student("zhaoliu",19);

        //把学生添加到集合
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);

        ts.add(ss);

        //遍历集合
        for(Student s : ts){
            System.out.println(s.getName()+","+s.getAge());
        }
    }
}
结果:
wangwu,18
lisi,19
zhaoliu,19
zhangsan,20

2、Map集合

2.1、Map集合概述

  • Interface Map<K,V>        K:键的类型;V:值的类型
  • 将键映射到值的对象;不能包含重复的键;每个键可以映射到最多一个值。

创建Map集合的对象:

  • 多态的方式;
  • 具体的实现类(如HashMap)。

2.2、Map集合的常用功能

方法名描述
V put(K key, V value)添加元素
V remove(Object key)根据键删除键值对元素
void clear()移除所有的键值对元素
boolean containsKey(Object key)判断集合是否包含指定的键
boolean congtainsValue(Object value)判断集合是否包含指定的值
boolean isEmpty()判断集合是否为空
int size()集合的长度,也就是集合中键值对的个数

代码演示:

package GPackage;

import java.util.HashMap;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        //创建集合对象
        Map<Integer,String> map = new HashMap<Integer,String>();

        //V put(K key, V value):添加元素
        map.put(2,"张三");
        map.put(4,"李四");
        map.put(6,"王五");
        System.out.println(map);
        System.out.println("--------");

        //V remove(Object key):根据键删除键值对元素,若找不到键值则返回null
        System.out.println(map.remove(4));
        System.out.println(map);
        System.out.println("--------");

        //void clear():移除所有的键值对元素(慎重使用)

        //boolean containsKey(Object key):判断集合是否包含指定的键
        System.out.println(map.containsKey(6));
        System.out.println("--------");

        //boolean congtainsValue(Object value):判断集合是否包含指定的值
        System.out.println(map.containsValue("李四"));
        System.out.println("--------");

        //boolean isEmpty():判断集合是否为空
        System.out.println(map.isEmpty());
        System.out.println("--------");

        //int size():集合的长度,也就是集合中键值对的个数
        System.out.println(map.size());
    }
结果:
{2=张三, 4=李四, 6=王五}
--------
李四
{2=张三, 6=王五}
--------
true
--------
false
--------
false
--------
2

2.3、Map集合的获取功能

方法名说明
V get(Object key)根据键获取值
Set<K> keySet()获取所有键的集合
Collection<V> values()获取所有值的集合
Set<Map.Entry<K,V>> entrySet()获取所有键值对对象的集合

代码演示:

package GPackage;

import java.util.HashMap;
import java.util.Map;

public class Test {
    public static void main(String[] args) {
        //创建集合对象
        Map<Integer,String> map = new HashMap<Integer,String>();

        //V put(K key, V value):添加元素
        map.put(2,"张三");
        map.put(4,"李四");
        map.put(6,"王五");
        System.out.println(map);
        System.out.println("--------");

        //V get(Object key):根据键获取值
        System.out.println(map.get(2));
        //Set<K> keySet():获取所有键的集合
        System.out.println(map.keySet());
        //Collection<V> values():获取所有值的集合
        System.out.println(map.values());
        //Set<Map.Entry<K,V>> entrySet():获取所有键值对对象的集合
    }
}
结果:
{2=张三, 4=李四, 6=王五}
--------
张三
[2, 4, 6]
[张三, 李四, 王五]

2.4、Map集合的遍历

2.4.1、遍历方式1

package GPackage;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        //创建集合对象
        Map<Integer, String> map = new HashMap<Integer, String>();

        //V put(K key, V value):添加元素
        map.put(2, "张三");
        map.put(4, "李四");
        map.put(6, "王五");
        System.out.println(map);
        System.out.println("--------");

        //获取所有键的集合,用keySet()方法实现
        Set<Integer> keySet = map.keySet();
        //遍历键的集合,获取到每一个键,用增强for实现
        for (Integer key : keySet) {
            //根据键去找值,用get(Object key)方法实现
            System.out.println(key + "," + map.get(key));
        }
    }
}


结果:
{2=张三, 4=李四, 6=王五}
--------
2,张三
4,李四
6,王五

2.4.2、遍历方式2

package GPackage;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Test {
    public static void main(String[] args) {
        //创建集合对象
        Map<Integer, String> map = new HashMap<Integer, String>();

        //V put(K key, V value):添加元素
        map.put(2, "张三");
        map.put(4, "李四");
        map.put(6, "王五");
        System.out.println(map);
        System.out.println("--------");

        //获取所有键值对对象的集合
        Set<Map.Entry<Integer,String>> eSet = map.entrySet();
        //遍历键值对对象的集合,得到每一个键值对对象
        for(Map.Entry<Integer,String> me : eSet){
            //根据键值对对象获取键和值
            System.out.println(me.getKey()+","+me.getValue());
        }
    }
}


结果:
{2=张三, 4=李四, 6=王五}
--------
2,张三
4,李四
6,王五

2.5、Map集合的实现类(子类)

HashMap和TreeMap,使用方法参照上述代码。

3、Collections类

3.1、Collections类概述

Collections在java.util包下,故使用时需要导包。Collections是一个具体的类(Collection是一个单列集合的顶层接口),仅由静态方法组成,是针对集合操作的工具类。

3.2、Collections类的常用方法

方法名描述

public static <T extends Comparable<? super T>>

void sort(List<T> list)

将指定的列表按升序排列
public static void reverse(List<?> list)反转指定列表中元素的顺序
public static void shuffle(List<?> list)只用默认的随机源随机排列指定的列表

代码演示:

package GPackage;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class Test {
    public static void main(String[] args) {
        //创建集合对象
        List<Integer> list = new ArrayList<Integer>();

        //添加元素
        Random rand = new Random();
        for (int i = 0; i < 10; i++) {
            list.add(rand.nextInt(100));
        }
        System.out.println("原列表:" + list);

        //public static <T extends Comparable<? super T>> void sort(List<T> list):将指定的列表按升序排列
        Collections.sort(list);
        System.out.println("排序后:" + list);

        //public static void reverse(List<?> list):反转指定列表中元素的顺序
        Collections.reverse(list);
        System.out.println("反转后:" + list);

        //public static void shuffle(List<?> list):只用默认的随机源随机排列指定的列表
        Collections.shuffle(list);
        System.out.println("随机置换后:" + list);
    }
}
结果:
原列表:[90, 66, 87, 60, 65, 49, 12, 44, 31, 86]
排序后:[12, 31, 44, 49, 60, 65, 66, 86, 87, 90]
反转后:[90, 87, 86, 66, 65, 60, 49, 44, 31, 12]
随机置换后:[87, 12, 86, 31, 49, 66, 90, 44, 60, 65]

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值