【Java基础】 (List、Set、Map、Stack、Queue)总结

【Java基础】 (List、Set、Map、Stack、Queue)总结

1、引入背景

如果一个程序只包含固定数量的且其生命周期都是已知的对象,那么这是一个非常简单的程序,而在通常情况下程序总在运行时才知道某些条件去创建对象,所以就不能通过创建命名的引用来持有每一个对象,因为你不知道这样的对象有多少个,java中有多种方案来保存对象的引用,下面就将介绍容器类来解决这样的问题。

2、Collection容器

其代表一个独立的元素序列,这些元素都遵循一条或者多条规则。

2.1、List

List可以将元素维持在特定序列中,常见的子类实现有

ArrayList 快速查询,插入删除效率低(类似数组)
LinkedList 快速插入删除、查询效率低(类似链表)

List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。 List集合允许加入重复元素,因为它可以通过索引来访问指定位置的集合元素。List集合默认按元素的添加顺序设置元素的索引。

如果涉及到“栈”、“队列”、“链表”等操作,请优先考虑用 List。至于是用哪个 List 则分如下:

1、对于需要快速插入、删除元素,则需使用 LinkedList。
2、对于需要快速访问元素,则需使用 ArrayList。
3、对于“单线程环境”或者“多线程环境,但是 List 仅被一个线程操作”,需要考虑使用非同步的类, 如果是“多线程环境,切 List可能同时被多个线程操作”,考虑使用同步的类(如Vector)。

LIST常用实例子类–ARRAYLIST

ArrayList是基于数组实现的List类,它封装了一个动态的增长的、允许再分配的Object[]数组。

Vector和ArrayList在用法上几乎完全相同,但由于Vector是一个古老的集合,所以Vector提供了一些方法名很长的方法, 但随着JDK1.2以后,java提供了系统的集合框架,就将Vector改为实现List接口,统一归入集合框架体系中

2.2、Set (equals)

Set集合类似于一个罐子,“丢进"Set集合里的多个对象之间没有明显的顺序。Set继承自Collection接口,不能包含有重复元素(记住,这是整个Set类层次的共有属性)。 Set判断两个对象相同不是使用”=="运算符,而是根据equals方法。也就是说,我们在加入一个新元素的时候,如果这个新元素对象和Set中已有对象进行注意equals比较都返回false,则Set就会接受这个新元素对象,否则拒绝。

因为Set的这个制约,在使用Set集合的时候,应该注意两点:

  1. 为Set集合里的元素的实现类实现一个有效的equals(Object)方法、
  2. 对Set的构造函数,传入的Collection参数不能包含重复的元素

用来保存不重复的元素,常用的实现有

HashSet
TreeSet 用于对结果进行排序。

SET常用实例化子类–HASHSET

HashSet是Set接口的典型实现,HashSet使用HASH算法来存储集合中的元素,因此具有良好的存取和查找性能。 当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据该HashCode值决定该对象在HashSet中的存储位置。 值得注意的是,HashSet集合判断两个元素相等的标准是两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法的返回值相等

它包含的方法:contains、add、remove、clear、clone、isEmpty、size、toArray

2.3、Stack

由于stack在当初设计时候有缺陷,所以现在不建议使用stack,如果要使用栈这种数据结构,建议使用LinkedList,LinkedList能够直接实现栈的所有功能和方法,所以建议使用LinkedList.

Stack是Vector提供的一个子类,用于模拟"栈"这种数据结构(后进先出LIFO)
方法:push、pop、peek、empty、seatch

2.4、Queue

Queue用于模拟"队列"这种数据结构(先进先出FIFO)。队列的头部保存着队列中存放时间最长的元素,队列的尾部保存着队列中存放时间最短的元素。 新元素插入(offer)到队列的尾部,访问元素(poll)操作会返回队列头部的元素,队列不允许随机访问队列中的元素。结合生活中常见的排队就会很好理解这个概念

队列是一种先进先出的容器,LinkedList实现了queue接口,所以可以通过向下转型来通LinkedList构造queue

Queue queue= new LinkedList();

其类图关系如下:
在这里插入图片描述

2.5、Map容器

Map。一组成对的“键值对”对象,允许你使用键查找值。
Map用于保存具有"映射关系"的数据,因此Map集合里保存着两组值,一组值用于保存Map里的key,另外一组值用于保存Map里的value。 key和value都可以是任何引用类型的数据。Map的key不允许重复,即同一个Map对象的任何两个key通过equals方法比较结果总是返回false。

关于Map,我们要从代码复用的角度去理解,java是先实现了Map,然后通过包装了一个所有value都为null的Map就实现了Set集合 Map的这些实现类和子接口中key集的存储形式和Set集合完全相同(即key不能重复) Map的这些实现类和子接口中value集的存储形式和List非常类似(即value可以重复、根据索引来查找)

常用实现有

HashMap 效率高、线程不安全(常用)
Hashtable 效率低、线程安全
TreeMap 用于排序

在这里插入图片描述

MAP常用子类,HASHMAP

和HashSet集合不能保证元素的顺序一样,HashMap也不能保证key-value对的顺序。 并且类似于HashSet判断两个key是否相等的标准也是:两个key通过equals()方法比较返回true、同时两个key的hashCode值也必须相等

HashMap常用方法:put、get、remove

3、List、Set、Map有什么区别?

List:

1.可以允许重复的对象。

2.可以插入多个null元素。

3.是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。

4.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问, 而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。

Set:

1.不允许重复对象

2.无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator 或者 Comparable 维护了一个排序顺序。

3.只允许一个 null 元素

4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。
最流行的是基于 HashMap 实现的 HashSet;TreeSet还实现了SortedSet接口, 因此 TreeSet是一个根据其 compare() 和compareTo() 的定义进行排序的有序容器。

Map:

1.Map不是collection的子接口或者实现类。Map是一个接口。

2.Map 的 每个 Entry 都持有两个对象,也就是一个键一个值,Map 可能会持有相同的值对象但键对象必须是唯一的。

3.TreeMap 也通过 Comparator 或者 Comparable 维护了一个排序顺序。

  1. Map 里你可以拥有随意个 null 值但最多只能有一个 null 键。

5.Map 接口最流行的几个实现类是 HashMap、LinkedHashMap、Hashtable 和 TreeMap。(HashMap、TreeMap最常用)

4、Iterator 和Iterable区别

Iterator是迭代器类,而Iterable是接口。

4.1Iterator是迭代器类

Iterator接口提供遍历任何Collection的接口。我们可以从一个Collection中使用迭代器方法来获取迭代器实例。迭代器取代了Java集合框架中的Enumeration。迭代器允许调用者在迭代过程中移除元素。
引入迭代器这个对象的目的是为了从一个collection或者Map的对象中取数据,而不必关心取数据的具体底层实现,如在List中add()和get()分别是插入元素和取出元素,而在Map中put(),才是插入元素,迭代器是一个对象,其目的是遍历和取出序列中的对象。而客户端程序员不必知道该序列底层是通过Set、List还是Map实现。
Iterator的功能:

1、使用iterator()方法要求返回一个iterator
2、使用next() 获得序列中下一个元素
3、使用hasNext()检查序列中是否还有元素
4、使用remove删除迭代器新近返回的元素

用法如下:

List<integer> list= new ArrayList<Integer>();
Iterator<Integer> it=list.iterator();

4.2 Iterable是接口

而对于iterable,任何实现iterable接口的类都可以使用迭代器进行遍历。

5、Collection和Collections区别

java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。

java.util.Collections 是一个包装类。它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

6、常见面试题

Q1:面试题:什么场景下使用list,set,map呢?
A1:

1.如果你经常会使用索引来对容器中的元素进行访问,那么 List 是你的正确的选择。
如果你已经知道索引了的话,那么 List 的实现类比如 ArrayList 可以提供更快速的访问;
如果经常添加删除元素的,那么肯定要选择LinkedList。

2.如果你想容器中的元素能够按照它们插入的次序进行有序存储,那么还是 List,因为 List 是一个有序容器,它按照插入顺序进行存储。

3.如果你想保证插入元素的唯一性,也就是你不想有重复值的出现,那么可以选择一个 Set 的实现类,比如 HashSet、LinkedHashSet 或者 TreeSet。 所有Set的实现类都遵循了统一约束比如唯一性,而且还提供了额外的特性比如 TreeSet 还是一个 SortedSet,所有存储于 TreeSet 中的元素可以使用 Java 里的 Comparator 或者 Comparable 进行排序。LinkedHashSet 也按照元素的插入顺序对它们进行存储。

4.如果你以键和值的形式进行数据存储那么 Map 是你正确的选择。你可以根据你的后续需要从 Hashtable、HashMap、TreeMap 中进行选择。

Q2:JAVA是如何定位元素位置的?
A2:通过hashcode定位。在集合内放入元素时放入值相同不同引用和相同引用的区别

Q3:ArrayList和LinkedList的增删查速度比较?
A3:当数据量较大时,大约在容量的1/10处开始,LinkedList的效率就开始没有ArrayList效率高了,特别到一半以及后半的位置插入时,LinkedList效率明显要低于ArrayList,而且数据量越大,越明显。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值