java集合与哈希列表

内容导航

Java语言中的集合就像一个容器,用来存放Java类的对象,并且可以实现常用的数据结构。本章将详细

介绍java中的集合,主要内容包括集合相关概念,List接口,Set接口和Map接口,以及ArrayList类,LinkedList类,HashSet类和HashMap类等,除此之外,还会介绍集合送代器Iterator。

Java集合概述

为什么用集合,应为数组有不足点,数组的短处:

  • 数组长度固定不变

  • 不便存储具有映射关系的数据

  • 数据变更效率低下

集合框架

java集合框架提供了一套性能优良,使用方便的接口和类,它门都位于Java。util包中,集合中的元素全部是对象,即Object类的实例,不同的集合类有不同的功能和特点,适合不同的场合。

从图中可以看出,Java的集合类主要由两个接口派生而成;Collection接口和Map接口。Collection接口和Map接口是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类。其中,Collection接口常用的子接口包含List接口和Set接口;另外一个重要接口是Map接口,它是独立一支,以上三者都是集合接口,其实实现类为Java中经常使用的集合类型。Java集合框架常用接口说明如表所示。此外,Java集合框架还包括相关的工具类(Iterator送代器接口,Arrays类和Collections类)。

名称

描述

Collection

  • 单值集合的跟接口,是最基本的集合接口

  • 一个Collection代表一组Object。java不是提供其实现类,只提供子接口(如List接口和Set接口)。

  • Collection接口存储一组可重复的无序列表对象

Set

继承Collection接口,存储一组不可重复的无序对象

List

  • 继承Collection接口,存储一组可重复的有序对象。

  • 元素顺序以元素插入的次序来放置元素,不会重新排序。

  • 通过索引访问数组元素,索引从0开始。

  • List接口常用的实现类有ArrayList类和LinkedList类

Map

  • 存储成对数据的根接口,可存储一组“键-值对”对象。

  • 提供键(key)到值(value)的映射,Map中的键不要求有序,不允许重复。值同样不要求有序,但允许重复。

  • 可以通过键找到对应的值

Iterator

集合送代器,能够遍历集合元素的接口

Collections

  • 与Collection是不同的概念,它提供了对集合对象进行基本操作的通用接口方法。

  • 包含各种有关集合操作的静态方法。

  • 是一个工具类,不能实例化

Collection接口

Collection接口是List接口,Set接口的父接口,该接口中定义的方法既可以操作Set集合,也可以用与操作List集合。Collection接口常用的方法如表所示。

方法

描述

boolean add(Object o)

用于向集合中添加一个元素,如果集合不允许重复且已包含了指定元素,则返回false

boolean addAll(Collection c)

将集合c里的所有元素添加到指定集合里,添加成功返回true

void clear()

清除集合中所有元素,将集合长度变为0

boolean contains(Object o)

判断集合中是否包含指定元素

boolean containsAll(Collection c)

判断集合中是否包含集合c里的所有元素

boolean remove(Object o)

删除集合中的指定元素o,当集合中包含了一个或多个元素o时,这些元素将被删除,删除成功返回true

int size()

返回集合里元素的个数

boolean retainAll(Collection c)

从集合中删除集合c里不包含的元素(相当于把调用该方法的集合变成该集合和集合c的交集),如果该方法改变了调用该方法的集合,则该方法返回true

boolean removeAll(Collection c)

从集合中删除集合c中包含的元素(相当于用调用该方法的集合减集合c),如果删除了一个或一个以上的元素,则该方法返回true

boolean isEmpty()

如果集合中不包含任何元素,则该方法返回true

Object[] toArray()

把集合转换成一个数组,所有的集合元素变成对应的数组元素

提示:

  1. Java集合中的元素全部是对象,是引用类型,不能存储基本数据类型元素。如果强制添加,则其会自动封装成对象。

  1. 使用System。out.println()方法输出集合数据时,需要调用集合类型本身的toString()方法,该方法会进一步调用集合元素的toString()方法。

  1. 集合中存储的元素为Object类的对象,属于引用数据类型,默认调用Object的toString()方法进行输出,输出格式为:getClass().getName()+"@"+Integer.toHexString(hashcode()) 即“该对象所属类全称的字符串@该对象哈希码的无符号的十六进制表示”

集合的遍历

当使用System.out.println()方法输出集合对象时,其将以【ele1,ele2……】的形式输出,这是因为所有的Collection实现类都重写了toString()方法,该方法可以一次性地输出集合中的所有元素。但是,如果想依次访问集合里的每一个元素,并实现对该元素的操作,则需要使用某种方式遍历集合元素。下面介绍遍历集合的两种方法。

  1. 使用Iterator接口遍历集合元素,Iterator接口定义的方法

方法

描述

boolean hasNext()

判断是否存在下一个遍历元素,存在则返回true

Object next()

返回遍历的下一个元素

void remove()

删除集合里上一次next()方法返回的元素

  1. 使用for循环遍历集合元素,语法:

for(数据类型type 送代变量名value:送代对象 object){
    //引用送代变量value的语句
}

List

List集合是一类存储元素有序,可重复的集合,集合中每个元素都有对应的索引。List集合允许使用重复元素,可以通过索引访问指定位置的集合元素。List集合默认按元素的添加顺序设置元素的索引,如果引为0,1,2,3……。

List概述

List接口作为Collection接口的子接口,可以使用Collection接口定义的全部方法。由于List集合是有序集合,所以List接口在Collection接口方法基础上,另外扩展了一些根据索引操作集合元素的方法。

List接口扩展的方法

方法

描述

void add(int index,Object element)

将元素(element)插入List集合的指定位置(index)

boolean addAll(int index,Collection c)

将集合c所包含的所有元素都插入List集合的指定位置(index)

Object get(int index)

返回集合index索引处的元素

int indexOf(Object o)

返回对象o在List集合中第一次出现的位置索引

int lastIndexOf(Object o)

返回对象o在List集合中最后一次出现的位置索引

Object remove(int index)

从集合中删除指定位置的元素

boolean remove(Object o)

从集合中删除指定对象

Object set(int index,Object element)

将index索引处的元素替换成Element对象,返回新元素

List subList(int fromIndex,int toIndex)

返回从索引包含(fromlndex)到索引不包括(toIndex)处所有集合元素组成的子集合

List集合比Collection接口扩充了更多的方法,而且这些方法操作起来很方便,需要通过List接口的子类实例化对象调用。常用的子类有ArrayList类和LinkedList类,它们的集合对象都可以容纳所有类型的元素对象,包括null,允许重复,并且保证元素按顺序存储。

ArrayList集合类

ArrayList类对数组进行了封装,实现了长度可变的数组。ArrayList集合存储数据的方式和数组相同,都是在内存中分配连续的空间。

LinkedList集合类

由于ArrayList集合采用了和数组相同的存储方式,在内存中分配连续的空间,当添加和删除非尾部元素时会导致后面所有元素的移动,性能低下,所以在插入,删除操作较频繁时,可以考虑使用LinkedList集合提高效率。

LinkedList集合存储数据的方式为双向链表存储方式,它的每个节点都有两个指针,分别指向直接后续和直接前驱。它提供了额外的addFirst(),addLast(),removeFirst()和removeLast()等方法,可以在链表的首部或尾部进行插入或删除操作。

LinkedList集合实现链表操作的常用方法

方法

描述

void addFirst(Object o)

在链表的首部添加元素

void addLast(Object 0)

在链表的未尾添加元素

Object getFirst()

返回链表中第一个元素

Object getLast()

返回链表中最后一个元素

Object removeFirst()

删除并返回链表中的第一个元素

Object removeLast()

删除并返回链表中的最后一个元素

小结:

ArrayList集合和LinkedList集合对比如下。

ArrayList集合的底层是数组。

优点:基于数组实现,读取操作效率高。

缺点:不适合频繁进行插入和删除操作,因为每次执行该类操作都需要频繁移动其中的元素。

LinkedLIst集合由双向链表实现,从任意一个节点开始,都可以很方便地访问它的前驱节点和后续节点。

优点:增加,删除操作只需要修改链表节点指针,无需进行频繁的移动。

缺点:遍历效率较低。

Set

Set接口和List接口一样,都是Collection的子接口,它类似于一个罐子,丢进Set集合里的多个对象没有明显的顺序。Set集合于Collection集合基本上一样,没有提供额外的方法,只是行为上略有不同,Set集合不允许包含重复元素。

HashSet集合

HashSet类是Set接口的典型实现,使用HashSet集合可以实现对无序不重复数据的存储,具有很好的存取和查找性能。它具有以下特征。

  • 不允许存储重复的元素。

  • 没有索引,没有包含索引的方法,不能使用索引遍历。

  • 是无序集合,存储元素和取出元素的顺序可能不一致。

Map

List集合和Set集合都可以存储一组数据元素,每个元素是一个对象,并且可以实现对这组数组元素的操作。当是,有时候需要存储具有映射关系的数据元素,如字典数据,可以通过中文找到对应的英文单词,每个元素由具有一对一关系的一组中英文数据组成,也就是一组成对的键-值对象,而不是单值数据,这样通过List集合和Set集合无法实现,需要使用到Map集合。

Map概述

Map集合可以存储若干个成对的键-值对象,提供键(Key)到值(value)的映射。其中key为Set集合类型,不要求有序,不允许重复;value同样不要求有序,但允许重复。因为Map接口与Collection接口不存在继承关系,所以Map集合对象不能使用Collection接口中定义的方法,而使用持有能够操作“键-值对”的方法。

Map接口的常用方法

Object put(Object key,Object value)

以“键-值对”的方式存储。

注意:键必须是唯一的,值可以重复。如果试图添加重复的键,那么最后加入的“键-值对”将替换掉原先的“键-值对”

Object get(Object key)

返回指定的键所对应的值;如果此Map集合中不包含指定的键,则返回null

int size()

返回元素个数

boolean remove(Object key)

删除指定的键映射的“键-值对”

Set keyset()

返回键的集合

Collection values()

返回值的集合

boolean containsKey(Object key)

若存在指定的键映射的“键-值对”,则返回true

Set entrySet()

返回“键-值对”集合

boolean isEmpty()

若不存在“键-值对”元素,则返回true

void clear()

删除该Map对象中所有“键-值对”

HashMap集合类

Map集合可以存储成对出现的“键-值对”元素,它的存储方式是哈希表。哈希表为散列表,是根据关键码值直接访问的数据结构。也就是说,它通过把关键码来映射到表中的一个位置来访问记录,以加快查找速度。存放记录的数组被称为散列表。使用这种方式存储数据的优点是查询指定元素效率高。

对比:

在Map接口的实现类中,除HashMap外,Hashtable对象也可以存储“键-值对”对象,Hashtable类与HashMap类具有相似的特征,Hashtable类是一个古老的Map接口实现类,Hashtable类和HashMap类之间存在着以下典型区别。

  • Hashtable类是线程安全的Map实现,但HashMap类是线程不安全的,HashMap性能更高,但如果多个线程访问一个Map集合对象,则应选择Hashtable类

  • Hashtable类不允许使用null作为key和value,HashMap类可以使用null作为key或value.

因为HashMap类里的key不能重复,所以在HashMap类里最多只有一个“键-值对”元素的key为null,但可以有多个“键-值对”元素的value为null。

HashMap集合的遍历

对于Map接口来说,其本身是不能直接使用送代(如Iterator,foreach)进行输出的。由于Map中的每个位置存入的是“键-值对”,而Iterator送代器每次只能找到一个值,可以先获取所有键的集合,通过遍历键的集合,找到每个键对应的值,

扩展资料:

在Map中定义了一个接口Map.Entry,用户保存形式如“key-value”的元素,即“键-值对”元素。

Map.Entry接口的常用方法

方法

描述

Object getKey()

取得此“键-值对”对应的key值

Object getValue()

取得此“键-值对”相对应的value值

int hashCode()

返回该“键-值对”的哈希码值

Object setValue(Object value)

用指定的值替换该“键-值对”的value值

泛型集合

泛型可以约束录入集合的元素类型,大大提高了数据安全性,从集合中取出数据无需进行类型,从而让代码更简洁,查询更加健壮。如果要锁定基本数据类型,那么要写该类型的包装类。

数据类型

包装类

整形

byte

Byte

short

Short

int

Integer

long

Long

浮点型

float

Float

double

Double

字符型

char

Character

应用泛型

泛型集合可以约束集合中元素的类型,它可以把类型当作参数一样传递。泛型集合的形式为List<E>,Map<K,V>等,其中<E>,<K,V>是集合类型形式的参数,可以在创建集合时,指定这些类型参数,即元素的数据类型,添加的元素必须为指定类型对象,保证数据的安全性。

public class Teacher {
    private int age;//年龄
    private String name;//年龄

    public Teacher() {
    }

    public Teacher(int age, String name) {
        this.age = age;
        this.name = name;
    }
public class Student {
    private String name;
    private String id;

    public Student() {
    }

    public Student(String name, String id) {
        this.name = name;
        this.id = id;
    }
public class Test {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList();
        list1.add(new Teacher(12,"小帅"));
        ArrayList<Teacher> j= list1;
        ArrayList<Teacher> a= arr();
        for (Teacher th:a){
            //打印到第二条的时候,必然报错,不用想的
            System.out.println(th.toString());
        }
        //可以先在数据类型定义泛型,后面就不需要了。
        ArrayList<Teacher> list = new ArrayList<>();
        //如果添加了其他类,那么就会报错
        //list.add(new Student("小破","12"));
        list.add(new Teacher(12,"zhu"));
    }
    public static ArrayList arr(){
        ArrayList list = new ArrayList();
        list.add(new Teacher(12,"qw"));
        list.add(new Student("12","19"));
        return list;
    }
}

本章总结

  • 集合弥补了数组的缺陷,它比数组更灵活更实用,可大大提高软件的开发效率,而且不同的集合可用于不同场合。

  • Java 的集合类主要由两个接口派生而出: Collection 接口和Map 接口及相关的工具类,这两个接口又包括了一些子接口或实现类。其中,Collection 接口又包含子两个子接口--List 接口和Set 接口,另外一个重要接口是Map 接口。

  • Collection 接口存储一组不唯一、无序的对象。

  • Set 接口继承 Collection 接口,存储一组唯一、无序的对象。

  • List 接口继承 Collection 接口,存储一组不唯一、有序的对象。

  • Map 接口存储一组成对的键-值对象,提供从 key到 value 的映射。key不要求有序,不允许重复;value 同样不要求有序,但允许重复。

  • Iterator 为集合而生,专门实现集合的遍历。它隐藏了各种集合实现类的内部细节,提供了遍历集合的统一编程接口。

  • ArrayList 类和数组采用相同的存储方式,它的优点在于遍历元素和随机访问元素的效率比较高。

  • LinkedList 类采用链表存储方式,优点在于插入,删除元素时效率比较高。

  • HashMap 类是最常见的 Map 实现类,它的存储方式是哈希表,优点是查询指定元素效率高。使用泛型集合在创建集合对象时指定集合中元素的类型,在从集合中取出元素时无需进行强制类型转换,避免了 ClassCastException 异常。

一份信心,一份努力,一份成功;十分信心,十分努力,十分成功

猜你喜欢

转载自blog.csdn.net/zouzxxi/article/details/129489662