java学习笔记11--集合总结

简介:

Java集合框架概述

集合就是将若干用途相同、近似的“数据”结合成一个整体。

集合从体系上分为三种:

(1) 列表(List):List集合区分元素的顺序,允许包含相同的元素。

(2) 集(Set):Set集合不区分元素的顺序,不允许包含相同的元素。

(3) 映射(Map):Map集合保存的”键”-“值”对,“键”不能重复,而且一个“键”只能对应一个“值”。

Java集合中只能保存引用数据类型,也就是保存的是对象的地址,而非对象本身。集合中元素相当于引用类型的变量。

JDK所提供的容器API全部位于java.util包中。

Java集合主要包括三种类型:Set(集),List(列表),Map(映射)。

Java集合类框图:

Collection和Iterator接口

在Collection接口中声明了适用于Java集合(只包括Set和List)的通用方法。因此Set和List对象可以调用以上方法,Map对象不可以。

Iterator接口隐藏了底层集合的数据结构,向客户程序提供了遍历各种数据集合的统一接口。

如果集合中的元素没有排序,Iterator遍历集合中元素的顺序是任意的,并不一定与集合中加入元素的顺序是一致的。

Collection接口中的方法:

boolean add(E o) 确保此 collection 包含指定的元素(可选操作)
void clear() 移除此 collection 中的所有元素(可选操作)
boolean contains(Object o) 如果此 collection 包含指定的元素,则返回 true
boolean isEmpty() 如果此 collection 不包含元素,则返回 true
Iterator<E> iterator() 返回在此 collection 的元素上进行迭代的迭代器 
boolean remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)
int size() 返回此 collection 中的元素数
Object[] toArray() 返回包含此 collection 中所有元素的数组

Collection方法举例:

public class javatest {  
    public static void main(String args[]) { 
        Collection c = new ArrayList();
        c.add("Hello World!");    //添加String类型对象
        c.add(new Integer(100));    //添加Integer类型对象
        c.add(new Float(2323.45f));    //添加Float类型对象
        System.out.println(c.size());
        System.out.println(c);
   }
}

List接口以及实现类

List是Collection的子接口,实现List接口的容器中存放的对象是有顺序的,而且可以重复。List容器中存放的对象都有一个整数型的序号,记录该对象在容器中的位置,可以根据序号来访问容器中的元素。

JDK提供实现List接口的类有ArrayList、LinkedList等。相关方法如下:

Object get(int index)
Object set(int index,Object obj)
void add(int index,Object obj)
Object remove(int index)
int indexOf(Object obj)
int lastIndexOf(Object obj)

List接口举例:

public class javatest {  
    public static void main(String args[]) { 
        List li=new ArrayList();
        for(int i=0;i<10;i++)
            li.add("a"+i);
        System.out.println(li);
        li.add(3,"a20");
        System.out.println(li);
        li.set(4,"a30");
        System.out.println(li);
        System.out.println((String)li.get(2));
        li.remove(0);
        System.out.println(li);
   }
}

运行结果如下:

[a0, a1, a2, a3, a4, a5, a6, a7, a8, a9]
[a0, a1, a2, a20, a3, a4, a5, a6, a7, a8, a9]
[a0, a1, a2, a20, a30, a4, a5, a6, a7, a8, a9]
a2
[a1, a2, a20, a30, a4, a5, a6, a7, a8, a9]

List接口的实现类-ArrayList

java.util.ArrayList实现了List接口,用于描述长度可变的数组列表(底层采用数组实现)。ArrayList允许元素取值为null,提供了一些新增的方法来操作列表的容量的大小。

public ArrayList()
public ArrayList(int initialCapacity)
public void ensureCapacity(int minCapacity)
public void trimToSize()

ArrayList举例:

ArrayList list=new ArrayList(6);
list.add("codingwu");
list.add(new Integer(10));
list.add(new Double(10.5));        
System.out.println(list.size());
Object item[]=list.toArray();
for(int i=0;i<item.length;i++)
    System.out.println(item[i]);
list.trimToSize();     

List接口的实现类-Vector

java.util.Vector实现了List接口,用于描述长度可变的数组向量(底层采用数组实现)。

与ArrayList的区别:Vector是线程安全的(同步),用在多线程环境中,运行效率慢。ArrayList不是线程安全的,用在单线程环境中。

Vector类的新增方法:

public Vector()
public Object elementAt(int index)
public void removeElement(int index)
public void insertElement(Object obj,int index)
public boolean removeElement(Object obj)
public void removeAllElements()
public Object toArray()

Map接口以及实现类

以该接口为根的集合类,用于存储“关键字”(key)和“值”(value)的元素对,其中每个关键字映射到一个值,当需要通过关键字实现对值的快速存取时使用

声明的抽象方法主要有:

查询方法、修改方法

两个主要实现类:

HashTable、HashMap

查询方法

int size() —— 返回Map中的元素个数

boolean isEmpty() —— 返回Map中是否包含元素,如不包括任何元素,则返回true

boolean containsKey(Object key) —— 判断给定的参数是否是Map中的一个关键字(key)

boolean containsValue(Object val) —— 判断给定的参数是否是Map中的一个值(value)

Object get(Object key) —— 返回Map中与给定关键字相关联的值(value)

Collection values() —— 返回包含Map中所有值(value)的Collection对象

Set keySet() ——返回包含Map中所有关键字(key)的Set对象

Set entrySet() —— 返回包含Map中所有项的Set对象 

修改方法

Object put(Object key, Object val) —— 将给定的关键字(key)/值(value)对加入到Map对象中。其中关键字(key)必须唯一,否则,新加入的值会取代Map对象中已有的值

void putAll(Map m) —— 将给定的参数Map中的所有项加入到接收者Map对象中

Object remove(Object key) —— 将关键字为给定参数的项从Map对象中删除

void clear() —— 从Map对象中删除所有的项

哈希表

也称为散列表,是用来存储群体对象的集合类结构,其两个常用的类是HashTable及HashMap

哈希表存储对象的方式与前面所讲的数组,Vector及ArrayList不同。数组、Vector及ArrayList中 对象的存储位置是随机的,即对象本身与其存储位置之间没有必然的联系。因此查找一个对象时,只能以某种顺序(如顺序查找,二分查找)与各个元素进行比较, 如果数组或向量中的元素数量很庞大时,查找的效率必然降低

哈希表中,对象的存储位置和对象的关键属性k之间有一个特定的对应关系f,我们称之为哈希(Hash)函数。它使每个对象与一个唯一的存储位置相对应。因而在查找时,只要根据待查对象的关键属性k,计算f(k)的值即可知其存储位置

哈希表相关的一些主要概念:

容量(capacity)—— 哈希表的容量不是固定的,随对象的加入,其容量可以自动扩充

关键字/键(key)—— 每个存储的对象都需要有一个关键字key,key可以是对象本身,也可以是对象的一部分(如对象的某一个属性)

哈希码(hash code)—— 要将对象存储到HashTable,就需要将其关键字key映射到一个整型数据,称为key的哈希码(hash code)

哈希函数(hash function)——返回对象的哈希码

项(item)—— 哈希表中的每一项都有两个域:关键字域key及值域value(即存储的对象)。key及value都可以是任意的Object类型的对象,但不能为空(null),HashTable中的所有关键字都是唯一的

装填因子(load factor)—— (表中填入的项数)/(表的容量)

构造方法:
Hashtable( ); // 初始容量为101,最大装填因子为0.75
Hashtable(int capacity);
Hashtable(int capacity, float maxLoadFactor);

Object put(Object key, Object value) —— 值value以key为其关键字加入到哈希表中,如果此关键字在表中不存在,则返回null,否则表中存储的value

View Code

Object get(Object key) —— 返回关键字为key的值value,如果不存在,则返回null。如

View Code

Object remove(Object key) —— 将键/值对从表中去除,并返回从表中去除的值,如果不存在,则返回null。如

View Code
boolean isEmpty() —— 判断哈希表是否为空
boolean containsKey(Object key) —— 判断给定的关键字是否在哈希表中
boolean contains(Object value) —— 判断给定的值是否在哈希表中
boolean containsValue(Object value) —— 判断给定的值是否在哈希表中
void clear() —— 将哈希表清空
Enumeration elements() —— 返回包含值的Enumeration对象
Enumeration keys() —— 返回包含关键字的Enumeration对象

HashMap类与HashTable类很相似,只是HashTable类不允许有空的关键字,而HashMap类允许

Set接口以及实现类

Set是最简单的集合,集合中的对象不按照特定的方式排序,并且没有重复的对象。Set接口主要有两个实现类:HashSet和TreeSet

Set集合里多个对象之间没有明显的顺序,基本与Collection方法相同。只是行为不同(Set不允许包含重复元素)。Set集合不允许重复 元素,是因为Set判断两个对象相同不是使用==运算符,而是根据equals方法。即两个对象用equals方法比较返回true

public class TestSet {
    public static void main(String[] args) {
        Set<String> books = new HashSet<String>();
        //添加一个字符串对象
        books.add(new String("Struts2权威指南"));
        //再次添加一个字符串对象,
        //因为两个字符串对象通过equals方法比较相等,所以添加失败,返回false
        boolean result = books.add(new String("Struts2权威指南"));
        System.out.println(result);
        //下面输出看到集合只有一个元素
        System.out.println(books);    
    }
}

程序运行结果:

false 
[Struts2权威指南]

说明:程序中,book集合两次添加的字符串对象明显不是一个对象(程序通过new关键字来创建字符串对象),当使用==运算符判断返回 false,使用equals方法比较返回true,所以不能添加到Set集合中,最后只能输出一个元素。Set接口中的知识,同时也适用于 HashSet、TreeSet和EnumSet三个实现类。

HashSet类

HashSet按Hash算法来存储集合的元素,因此具有很好的存取和查找性能。

 HashSet的特点:

(1)HashSet不是同步的,多个线程访问是需要通过代码保证同步 

(2)集合元素值可以使null。

HashSet集合判断两个元素相等的标准是两个对象通过equals方法比较相等,并且两个对象的hashCode()方法返回值也相等。

//类A的equals方法总是返回true,但没有重写其hashCode()方法  
class A  
{  
    public boolean equals(Object obj)  
    {  
        return true;  
    }  
}  
//类B的hashCode()方法总是返回1,但没有重写其equals()方法  
class B  
{  
    public int hashCode()  
    {  
        return 1;  
    }  
}  
//类C的hashCode()方法总是返回2,但没有重写其equals()方法  
class C  
{  
    public int hashCode()  
    {  
        return 2;  
    }  
    public boolean equals(Object obj)  
    {  
        return true;  
    }  
}  
public class TestHashSet  
{  
    public static void main(String[] args)   
    {  
        HashSet<Object> books = new HashSet<Object>();  
        //分别向books集合中添加2个A对象,2个B对象,2个C对象  
        books.add(new A());  
        books.add(new A());  
        books.add(new B());  
        books.add(new B());  
        books.add(new C());  
        books.add(new C());  
        System.out.println(books);  
    }  
} 

程序运行结果:

[B@1, B@1, C@2, A@b5dac4, A@9945ce] 

TreeSet类

TreeSet是SortedSet接口的唯一实现,TreeSet可以确保集合元素处于排序状态(元素是有序的)。

TreeSet提供的几个额外方法:

Comparator comparttor(): 返回当前Set使用的Compara投入,或者返回null,表示以自然方式排序。  

Object first():返回集合中的第一个元素。  

Object last():返回集合中的最后一个元素。  

Objiect lower(Object e):返回集合中位于指定元素之前的元素(即小于指定元素的最大元素,参考元素可以不是TreeSet的元素)。  

Object higher(Object e):返回集合中位于指定元素之后的元素(即大于指定元素的最小元素,参考元素可以不需要TreeSet的元素)。  

SortedSet subSet(fromElement, toElement):返回此Set的子集,范围从fromElement(包含大于等于)到toElement(不包含小于)。  

SortedSet headSet(toElement):返回此Set的子集,由小于toElement的元素组成。  

SortedSet tailSet(fromElement):返回此Set的子集,由大于或等于fromElement的元素组成。 

public class TestTreeSetCommon  
{  
    public static void main(String[] args)   
    {  
        TreeSet<Integer> nums = new TreeSet<Integer>();  
        //向TreeSet中添加四个Integer对象  
        nums.add(5);  
        nums.add(2);  
        nums.add(10);  
        nums.add(-9);  
        //输出集合元素,看到集合元素已经处于排序状态  
        System.out.println(nums);  
        //输出集合里的第一个元素  
        System.out.println(nums.first());  
        //输出集合里的最后一个元素  
        System.out.println(nums.last());  
        //返回小于4的子集,不包含4  
        System.out.println(nums.headSet(4));  
        //返回大于5的子集,如果Set中包含5,子集中还包含5  
        System.out.println(nums.tailSet(5));  
        //返回大于等于-3,小于4的子集。  
        System.out.println(nums.subSet(-3 , 4));  
    }  
} 

说明:由运行结果可以看出,TreeSet并不是根据元素的插入顺序进行排序,而是根据元素实际值来进行排序。TreeSet采用红黑树的数据结构对元素进行排序,具体排序内容会在后续文章中说明。

目录
相关文章
|
2月前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
41 6
|
2月前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
39 3
|
2月前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
33 2
|
2月前
|
存储 算法 Java
Java Set因其“无重复”特性在集合框架中独树一帜
【10月更文挑战第14天】Java Set因其“无重复”特性在集合框架中独树一帜。本文深入解析Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定的数据结构(哈希表、红黑树)确保元素唯一性,并提供最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的`hashCode()`与`equals()`方法。
31 3
|
16天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
25 2
|
16天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
21天前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
21天前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
21天前
|
Java 开发者
|
2月前
|
安全 Java 程序员
深入Java集合框架:解密List的Fail-Fast与Fail-Safe机制
本文介绍了 Java 中 List 的遍历和删除操作,重点讨论了快速失败(fail-fast)和安全失败(fail-safe)机制。通过普通 for 循环、迭代器和 foreach 循环的对比,详细解释了各种方法的优缺点及适用场景,特别是在多线程环境下的表现。最后推荐了适合高并发场景的 fail-safe 容器,如 CopyOnWriteArrayList 和 ConcurrentHashMap。
59 5
下一篇
无影云桌面