Java集合(Collection)简介

本文详细介绍了Java集合框架中的Collection接口,包括List(如ArrayList、LinkedList和Vector)和Set(如HashSet、TreeSet)的特性和区别。此外,还探讨了Iterator迭代器的使用方法。同时,文章涵盖了Map接口的实现如HashMap和Hashtable的差异,并讨论了集合面试题,如Collection和Collections的区别、集合与数组的差异以及ArrayList、Vector和LinkedList的性能特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Collection(集合)


Collection

  • List : Vector, ArrayList , LinkedList
  • Set : HashSet, TreeSet

List 元素是有序的、可重复

有序的 collection,可以对列表中每个元素的插入位置进行精确地控制。

可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

可存放重复元素,元素存取是有序的。

Vector : 底层数据结构是数组结构,线程安全,但速度慢,已被ArrayList替代。

ArrayList :线程不安全,查询速度快,底层数据结构是数组结构。

LinkedList :线程不安全。增删速度快,底层数据结构是列表结构。


Set(集合) 元素无序的、不可重复。

取出元素的方法只有迭代器。不可以存放重复元素,元素存取是无序的。


HashSet:线程不安全,存取速度快。依赖的是元素的hashCode方法和euqals方法,保证元素唯一性。

TreeSet:线程不安全,可以对Set集合中的元素进行排序。通过compareTo或者compare方法中的来保证元素的唯一性。元素是以二叉树的形式存放的。

HashMap,HashSet,ArrayList都不具备线程安全。

可以用 Set s=Collections.synchronizedSet(new Hashset<…>());
Map m=Collections.synchronizedMap(new HashMap<…>());
List l=Collections.synchronizedList(new ArrayList<…>());

获得被同步后的版本。



Iterator:迭代器

它是Java集合的顶层接口(不包括 map 系列的集合,Map接口 是 map 系列集合的顶层接口),主要包含三个重要方法:

  • Object next():返回迭代器刚越过的元素的引用,返回值是 Object,需要强制转换成自己需要的类型

  • boolean hasNext():判断容器内是否还有可供访问的元素

  • void remove():删除迭代器刚越过的元素

所以除了 map 系列的集合,我们都能通过迭代器来对集合中的元素进行遍历。

这里我们引用一个Iterator 的实现类 ArrayList 来看一下迭代器的使用:

 //产生一个 List 集合,典型实现为 ArrayList。
          List list = new ArrayList();
          //添加三个元素
          list.add("Tom");
          list.add("Bob");
          list.add("Marry");
          //构造 List 的迭代器
          Iterator it = list.iterator();
          //通过迭代器遍历元素
          while(it.hasNext()){
             Object obj = it.next();
             System.out.println(obj);
         }



Map:

  • HashMap
  • Hashtable
  • TreeMap

Map 是一个双列集合,以键值的形式存放数据。

Hashtable:线程安全,速度快。底层是哈希表数据结构。是同步的。不允许null作为键,null作为值。

HashMap:线程不安全,速度更快。底层也是哈希表数据结构。是不同步的。允许null作为键,null作为值。替代了Hashtable.

在JDK1.6,JDK1.7中,HashMap采用位桶+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。
但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。

而JDK1.8中,HashMap采用位桶+链表+红黑树实现,
当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

l |–LinkedHashMap: 可以保证HashMap集合有序。存入的顺序和取出的顺序一致。

TreeMap:可以用来对Map集合中的键进行排序.


Hashtable与HashMap简单总结如下:
  • 1.Hashtable是Dictionary的子类,HashMap是Map接口的一个实现类;
  • 2.Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。
即是说,在多线程应用程序中,不用专门的操作就安全地可以使用Hashtable了;
而对于HashMap,则需要额外的同步机制。
但HashMap的同步问题可通过Collections的一个静态方法得到解决:
Map Collections.synchronizedMap(Map m);
这个方法返回一个同步的Map,这个Map封装了底层的HashMap的所有方法,使得底层的HashMap即使是在多线程的环境中也是安全的。
  • 3.在HashMap中,null可以作为键,也可以作为value,(key不可重复,value可重复)这样的键只有一个;因此,在HashMap中不能由get()方法来判断HashMap中是否存在某个键,而应该用containsKey()方法来判断。




集合面试题


一.Collection 和 Collections的区别

  • Collection是集合类的上级接口,子接口主要有Set 和List。

  • Collections是针对集合类的一个帮助类,提供了操作集合的工具方法:一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

二.集合与数组的区别

  • 集合与数组都是容器,数组大小固定,只能存储相同数据类型的数据,集合大小可动态扩展,可以存储各种类型的数据;
  • 集合只能存放对象,如果放一个int类型的数,集合会自动转成它的包装类再进行存储,数组可以存放基本数据类型。
转换:

数组转换为集合: Arrays.asList(数组)

集合转换为数组: 集合.toArray();

三.ArrayList和Vector的区别

(1)同步性:

Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。

如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。

(2)数据增长:

ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间。

Vector默认增长为原来两倍,而ArrayList的增长为原来的1.5倍。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小。

四.HashMap和Hashtable的区别

主要从三方面来说:

一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现

二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的

三.值:只有HashMap可以让你将空值作为一个表的条目的key或value

五.List、Map、Set三个接口,存取元素时,各有什么特点????

  • 首先,List与Set具有相似性,它们都是单列元素的集合,所以,它们有一个共同的父接口,叫Collection。Set里面不允许有重复的元素,所谓重复,即不能有两个相等(注意,不是仅仅是相同)的对象 ,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。Set取元素时,没法说取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。

  • List表示有先后顺序的集合, 注意,不是那种按年龄、按大小、按价格之类的排序。当我们多次调用add(Obj e)方法时,每次加入的对象就像火车站买票有排队顺序一样,按先来后到的顺序排序。有时候,也可以插队,即调用add(int index,Obj e)方法,就可以指定当前对象在集合中的存放位置。一个对象可以被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并不是把这个对象本身存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个索引指向了这个对象。List除了可以以Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以调用get(index i)来明确说明取第几个。

  • Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key 所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。

六.说出ArrayList,Vector, LinkedList的存储性能和特性。

  • 1.ArrayList和Vector都是使用数组方式存储数据,都允许直接按序号索引元素,但是索引数据快而插入数据慢。Vector缺省情况下自动增长原来一倍的数组长度,ArrayList是原来的50%。

  • 2.Vector由于使用了synchronized方法(线程安全),ArrayList非线程安全,Vector通常性能上较ArrayList差。

  • 3.LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快查询较慢。LinkedList也是线程不安全的。

    总结:如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。 如果要考虑到线程安全问题,可以使用Vector。

七.Collection框架中实现比较要实现什么接口

comparable/comparator

八.Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

= =equals()和= =的区别= =

  • = =主要用在基本数据类型及引用,来比较两个变量的值是否相等,如果一个变量只想的数据是对象类型,那么= = 比较两个变量指向的内存地址是否相同。
  • equals 方法是用于比较两个独立对象的内容是否相同,就好比去比较两个人的长相是否相同,它比较的两个对象是独立的。
  • ==方法决定引用值是否指向同一对象 ,equals方法在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

Set 里的元素是不能重复的,元素重复与否先调用hashCode方法,如果不相同,证明不相等。如果相同,再调用equals方法,如果equals方法相同,证明相等,不相同,证明不相等。

集合中是否包含某一个元素用contains来判断。

九.你所知道的集合类都有哪些主要方法?

我记的不是方法名,而是思想,我知道它们都有增删改查的方法,但这些方法的具体名称,我记得不是很清楚,对于set,大概的方法是add,remove, contains;
对于map,大概的方法就是put,remove,contains等,因为,我只要在eclispe下按点操作符,很自然的这些方法就出来了。我记住的一些思想就是List类会有get(int index)这样的方法,因为它可以按顺序取元素,而set类中没有get(int index)这样的方法。
List和set都可以迭代出所有元素,迭代时先要得到一个iterator对象,所以,set和list类都有一个iterator方法,用于返回那个iterator对象。
map可以返回三个集合,一个是返回所有的key的集合,另外一个返回的是所有value的集合,再一个返回的key和value组合成的EntrySet对象的集合,map也有get方法,参数是key,返回值是key对应的value。

十.两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对?

对。

如果对象要保存在HashSet或HashMap中,它们的equals相等,那么,它们的hashcode值就必须相等。

如果不是要保存在HashSet或HashMap,则与hashcode没有什么关系了,这时候hashcode不等是可以的,例如arrayList存储的对象就不用实现hashcode,当然,我们没有理由不实现,通常都会去实现的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值