一,集合简介

1.1 集合由来:

对象的存储:①数组(基本数据类型  & 引用数据类型)  ②集合(引用数据类型)
    >数组存储数据的弊端:长度一旦初始化以后,就不可变;真正给数组元素赋值的个数没有现成的方法可用。

当增加元素时,需要对数组重新定义,太麻烦,Java内部给我们提供了集合类(容器)包括collection集合和map集合,能存储任意对象,长度是可变的,随着元素的增加而增加,随着元素的减少而减少。

1.2:数组和集合的区别
    * 区别1 : 
        * 数组既可以存储基本数据类型,又可以存储引用数据类型,基本数据类型存储的是值,引用数据类型存储的是地址值
        * 集合只能存储引用数据类型(对象)集合中也可以存储基本数据类型,但是在存储的时候会自动装箱变成对象
    * 区别2:
        * 数组长度是固定的,不能自动增长
        * 集合的长度的是可变的,可以根据元素的增加而增长
1.3:数组和集合什么时候用
        * 1,如果元素个数是固定的推荐用数组
        * 2,如果元素个数不是固定的推荐用集合

二、集合框架体系

2.1.1简单的collection接口继承体系图

Collection接口下还有queue接口,通常使用较少

Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。

JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List)实现。

在 Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成 Object 类型处理;从 Java5 增加了泛型以后,Java 集合可以记住容器中对象的数据类型.

2.1.2 Collection接口常用方法:

2.1.3 使用 Iterator 接口遍历集合元素

Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。

所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。

Iterator 仅用于遍历集合,Iterator 本身并不提供承装对象的能力。如果需要创建 Iterator 对象,则必须有一个被迭代的集合。

2.1.4 Iterator接口的方法

在调用it.next()方法之前必须要调用it.hasNext()进行检测。若不调用,且下一条记录无效,直接调用it.next()会抛出NoSuchElementException异常。

并发修改异常产生的原因及解决方案。

并发修改异常产生的原因及解决方案
* A:案例演示* 需求:我有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。List list = new ArrayList();list.add("a");list.add("b");list.add("world");list.add("d");list.add("e");/*Iterator it = list.iterator();while(it.hasNext()) {String str = (String)it.next();if(str.equals("world")) {list.add("javaee");           //这里会抛出ConcurrentModificationException并发修改异常}}*/* B:ConcurrentModificationException出现* 迭代器遍历,集合修改集合
* C:解决方案* a:迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)* b:集合遍历元素,集合修改元素ListIterator lit = list.listIterator();        //如果想在遍历的过程中添加元素,可以用ListIterator中的add方法while(lit.hasNext()) {String str = (String)lit.next();if(str.equals("world")) {lit.add("javaee");   //list.add("javaee");}}

2.1.4 使用 foreach 循环遍历集合元素

•Java 5 提供了 foreach 循环迭代访问 Collection

2.2.1  简单的Map接口继承体系图

 2.2.2 Map接口常用方法

添加、删除操作:

Object put(Object key,Object value)

Object remove(Object key)

void putAll(Map t)

void clear()

元素查询的操作:

Object get(Object key)

boolean containsKey(Object key)

boolean containsValue(Object value)

int size()

boolean isEmpty()

boolean equals(Object obj)

元视图操作的方法:

Set keySet()

Collection values()

Set entrySet()

三、LIst接口及实现类

Java中数组用来存储数据的局限性

List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。

List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。

JDK API中List接口的实现类常用的有:ArrayList、LinkedList和Vector。

3.1 List 集合里添加了一些根据索引来操作集合元素的方法

void add(int index, Object ele)

boolean addAll(int index, Collection eles)

Object get(int index)

int indexOf(Object obj)

int lastIndexOf(Object obj)

Object remove(int index)

Object set(int index, Object ele)

List subList(int fromIndex, int toIndex)

 3.2 List实现类之一:ArrayList

ArrayList 是 List 接口的典型实现类

本质上,ArrayList是对象引用的一个变长数组

ArrayList 是线程不安全的,而 Vector 是线程安全的,即使为保证 List 集合线程安全,也不推荐使用Vector

Arrays.asList(…) 方法返回的 List 集合既不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…)  返回值是一个固定长度的 List 集合

3.3 List实现类之二:LinkedList

对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高

新增方法:

void addFirst(Object obj)

void addLast(Object obj

Object getFirst()

Object getLast()

Object removeFirst()

removeLast()

3.4 List 实现类之三:Vector

Vector 是一个古老的集合,JDK1.0就有了。大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。

在各种list中,最好把ArrayList作为缺省选择。当插入、删除频繁时,使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。

新增方法:

void addElement(Object obj)

void insertElementAt(Object obj,int index)

void setElementAt(Object obj,int index)

void removeElement(Object obj)

void removeAllElements()

小结:

A:List的三个子类的特点

        ArrayList:
            底层数据结构是数组,查询快,增删慢。
            线程不安全,效率高。
        Vector:
            底层数据结构是数组,查询快,增删慢。
            线程安全,效率低。
        Vector相对ArrayList查询慢(线程安全的)
        Vector相对LinkedList增删慢(数组结构)
        LinkedList:
            底层数据结构是链表,查询慢,增删快。
            线程不安全,效率高。

Vector和ArrayList的区别
            Vector是线程安全的,效率低
            ArrayList是线程不安全的,效率高
        共同点:都是数组实现的
        ArrayList和LinkedList的区别
            ArrayList底层是数组结果,查询和修改快
            LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
        共同点:都是线程不安全的
* B:List有三个儿子,我们到底使用谁呢?
        查询多用ArrayList
        增删多用LinkedList
        如果都多ArrayList

四、Set接口及实现类

Set接口是Collection的子接口,set接口没有提供额外的方法

Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。

Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals 方法

4.1 Set实现类之一:HashSet

HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。

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

HashSet 具有以下特点:

不能保证元素的排列顺序

HashSet 不是线程安全的

集合元素可以是 null

当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值决定该对象在 HashSet 中的存储位置。

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

hashCode() 方法

如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。

对于存放在Set容器中的对象,对应的类一定要重写equals()hashCode(Object obj)方法,以实现对象相等规则。

重写 hashCode() 方法的基本原则

在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值

当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等

对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值

4.2 Set实现类之二:LinkedHashSet

LinkedHashSet 是 HashSet 的子类

LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,但它同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的。

LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全部元素时有很好的性能。

LinkedHashSet 不允许集合元素重复。

4.3 Set实现类之三:TreeSet

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

Comparator comparator()

Object first()

Object last()

Object lower(Object e)

Object higher(Object e)

SortedSet subSet(fromElement, toElement)

SortedSet headSet(toElement)

SortedSet tailSet(fromElement)

TreeSet 两种排序方法:自然排序定制排序。默认情况下,TreeSet 采用自然排序。

五、排序

5.1 排  序——自然排序

自然排序:TreeSet 会调用集合元素的 compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序排列

如果试图把一个对象添加到 TreeSet 时,则该对象的类必须实现 Comparable 接口。

实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小。

Comparable 的典型实现

BigDecimal、BigInteger 以及所有的数值型对应的包装类:按它们对应的数值大小进行比较

Character:按字符的 unicode值来进行比较

Boolean:true 对应的包装类实例大于 false 对应的包装类实例

String:按字符串中字符的 unicode 值进行比较

Date、Time:后边的时间、日期比前面的时间、日期大

向 TreeSet 中添加元素时,只有第一个元素无须比较compareTo()方法,后面添加的所有元素都会调用compareTo()方法进行比较。

因为只有相同类的两个实例才会比较大小,所以向 TreeSet 中添加的应该是同一个类的对象

对于 TreeSet 集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过 compareTo(Object obj) 方法比较返回值

当需要把一个对象放入 TreeSet 中,重写该对象对应的 equals() 方法时,应保证该方法与 compareTo(Object obj) 方法有一致的结果:如果两个对象通过 equals() 方法比较返回 true,则通过 compareTo(Object obj) 方法比较应返回 0

5.2 排  序——定制排序

TreeSet的自然排序是根据集合元素的大小,进行元素升序排列。如果需要定制排序,比如降序排列,可通过Comparator接口的帮助。需要重写compare(T o1,T o2)方法。

利用int compare(T o1,T o2)方法,比较o1和o2的大小:如果方法返回正整数,则表示o1大于o2;如果返回0,表示相等;返回负整数,表示o1小于o2。

要实现定制排序,需要将实现Comparator接口的实例作为形参传递给TreeSet的构造器。

此时,仍然只能向TreeSet中添加类型相同的对象。否则发生ClassCastException异常。

使用定制排序判断两个元素相等的标准是:通过Comparator比较两个元素返回了0。

六、Map接口实现类

Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value

Map 中的 key 和  value 都可以是任何引用类型的数据

Map 中的 key 用Set来存放,不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法。

常用String类作为Map的“键”。

key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到唯一的、确定的 value。

6.1 Map实现类之一:HashMap

lMap接口的常用实现类:HashMap、TreeMap和Properties。

lHashMap是 Map 接口使用频率最高的实现类。

l允许使用null键和null值,与HashSet一样,不保证映射的顺序。

lHashMap 判断两个 key 相等的标准是:两个 key 通过 equals() 方法返回 true,hashCode 值也相等。

lHashMap 判断两个 value相等的标准是:两个 value 通过 equals() 方法返回 true。

6.2 Map实现类之二:LinkedHashMap

LinkedHashMap 是 HashMap 的子类

与LinkedHashSet类似,LinkedHashMap 可以维护 Map 的迭代顺序:迭代顺序与 Key-Value 对的插入顺序一致

6.3 Map实现类之三:TreeMap

TreeMap存储 Key-Value 对时,需要根据 key-value 对进行排序。TreeMap 可以保证所有的 Key-Value 对处于有序状态。

TreeMap 的 Key 的排序:

自然排序:TreeMap 的所有的 Key 必须实现 Comparable 接口,而且所有的 Key 应该是同一个类的对象,否则将会抛出 ClasssCastException

定制排序:创建 TreeMap 时,传入一个 Comparator 对象,该对象负责对 TreeMap 中的所有 key 进行排序。此时不需要 Map 的 Key 实现 Comparable 接口

lTreeMap判断两个key相等的标准:两个key通过compareTo()方法或者compare()方法返回0。

l若使用自定义类作为TreeMap的key,所属类需要重写equals()和hashCode()方法,且equals()方法返回true时,compareTo()方法应返回0。

6.4 Map实现类之四:Hashtable

Hashtable是个古老的 Map 实现类,线程安全。

与HashMap不同,Hashtable 不允许使用 null 作为 key 和 value

与HashMap一样,Hashtable 也不能保证其中 Key-Value 对的顺序

Hashtable判断两个key相等、两个value相等的标准,与hashMap一致。

6.5 Map实现类之五:Properties

lProperties 类是 Hashtable 的子类,该对象用于处理属性文件

l由于属性文件里的 key、value 都是字符串类型,所以 Properties 里的 key 和 value 都是字符串类型

l存取数据时,建议使用setProperty(String key,String value)方法和getProperty(String key)方法

Properties pros = new Properties();
pros.load(new FileInputStream("jdbc.properties"));
String user = pros.getProperty("user");
System.out.println(user);

七、操作集合的工具类Collections(操作数组的工具类:Arrays)

Collections 是一个操作 Set、List 和 Map 等集合的工具类

Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法

排序操作(均为static方法)

reverse(List):反转 List 中元素的顺序

shuffle(List):对 List 集合元素进行随机排序

sort(List):根据元素的自然顺序对指定 List 集合元素按升序排序

sort(List,Comparator):根据指定的 Comparator 产生的顺序对 List 集合元素进行排序

swap(List,int, int):将指定 list 集合中的 i 处元素和 j 处元素进行交换

查找、替换

Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素

Object max(Collection,Comparator):根据 Comparator 指定的顺序,返回给定集合中的最大元素

Object min(Collection)

Object min(Collection,Comparator)

int frequency(Collection,Object):返回指定集合中指定元素的出现次数

void copy(List dest,List src):将src中的内容复制到dest中

boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值

同步控制

Collections 类中提供了多个 synchronizedXxx() 方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题

八、基础面试题

Collection 和 Collections的区别
答:Collection是集合类的上级接口,继承自它的接口主要有Set 和List.
Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作


Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别
答:Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等
    equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容
    和类型相配的话,返回真


List, Set, Map是否继承自Collection接口
答: List,Set是,Map不是


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


说出ArrayList,Vector, LinkedList的存储性能和特性
答:ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和
插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以
索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList
差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时
只需要记录本项的前后项即可,所以插入速度较快。


HashMap和Hashtable的区别
答:HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap
允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
    HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。
    HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让
人引起误解。 
    Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
    最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要
自己为它的方法实现同步,而HashMap 就必须为之提供外同步。 
    Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。


ArrayList和Vector的区别,HashMap和Hashtable的区别
答:就ArrayList与Vector主要从二方面来说.
一.同步性:Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的
二.数据增长:当需要增长时,Vector默认增长为原来一培,而ArrayList却是原来的一半
就HashMap与HashTable主要从三方面来说。
一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
三.值:只有HashMap可以让你将空值作为一个表的条目的key或value

Java基础-------集合框架相关推荐

  1. java基础—集合框架

    java基础-集合框架 JDK1.2开始引入了集合框架的概念,以弥补java中只有数组这种容器的单一问题,这些框架多数由接口构成,另外也包含了一些对于接口实现的类,其中这些接口的最上层接口为java. ...

  2. Java基础—集合框架(三)

    一Map集合 二Map扩展知识 集合框架(三) 一.Map集合 1.概述 Map集合用于存储键值对,且它保证键的唯一性,并且每个键最多只能映射一个值.Map集合是Set集合的底层实现,其和Collec ...

  3. Java 基础 —— 集合框架概述

    一.集合框架图 Java 集合框架主要包括两种类型的容器:一种是集合(Collection),存储一个元素集合:另一种是图(Map),存储键/值对映射.Collection 接口又有 3 种子类型:L ...

  4. Java基础 - 集合框架(5) : Map集合、Collections

    1. Map集合的概述和特点 将键映射到值的对象 一个映射不能包含重复的键 每个键最多只能映射到一个值 2. Map和Collection的区别 ? A. Map 存储的是键值对形式的元素,键唯一,值 ...

  5. Java基础 - 集合框架(3) : List的子类、泛型、可变参数

    1. List的子类特点 ArrayList : 底层数据结构是数组,查询快,增删慢. 线程不安全,效率高. Vector : 底层数据结构是数组,查询快,增删慢.线程安全,效率低. LinkedLi ...

  6. J2EE基础集合框架之Set

    今天将进行介绍的是J2EE基础集合框架之Set,其主要分为四个点 目录 1,set集合特点&遍历集合 2,set集合去重原理 3,set集自然排序接口 4,set集合比较器排序 1,set集合 ...

  7. java三大集合框架(面试知识储备精华篇)

    java三大集合框架 :  set  list   map 如上图 set list 都属于collection的子接口(collection为顶层接口) Map 不属于collection接口 Se ...

  8. JAVA基础---集合(一)--集合框架概述

    为什么用集合如何合理用集合,以及如何实现的和他们的实现原理,如果搞清了对于之后学习其他知识和开发是很有大帮助性的. 什么是集合框架? 集合框架是表示和操作集合的统一体系结构.所有集合框架都包含以下内容 ...

  9. Java学习----集合框架总结

    集合框架总结: Collection接口:Set接口:HashSet//对象必须实现hashCode方法,元素没有顺序呢,效率比LinkedHashSet高LinkedHashSet//是HashSe ...

最新文章

  1. java实现窗口透明_java实现窗口透明
  2. vc编程中出现 fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include stdafx.h”?...
  3. js uri解码_js进行URL编码(escape,encodeURI,encodeURIComponent)
  4. 在Atlas服务器端实现中推荐使用Web Service而不是Page Method
  5. Python学习笔记(五)—LOOP 循环
  6. Ubuntu上: insufficient permissions for device解决
  7. 【医疗影像处理】对分割的mask做处理,保留最大联通区域
  8. Win11系统使用DISM命令备份驱动程序的方法
  9. matlab%低通滤波器设计,matlab 低通滤波器设计及实现
  10. maxon电机/步科电机 CANOpen协议指令速度模式
  11. 中国移动科普:为什么手机移动网络要叫 “蜂窝移动网络”
  12. 假设检验的基本原理以及思想和方法
  13. android 光晕动画,充电动画软件下载
  14. 2015年3月1日起停止提供4年或5年SSL证书
  15. 什么是命名数据网络NDN?
  16. 关于最近GD32F103替代STM32F103方案个人记录
  17. Java中单引号和双引号的区别
  18. CAN通信控制TH-02机器狗电机 (仿MIT cheetah mini电机 )
  19. JB出品,下一代IDE!!
  20. npm安装的时候报错npm nodejs\node_cache\_cac

热门文章

  1. 我如何开始使用Node.js [关闭]
  2. win11任务栏怎么更换颜色 win11任务栏更换颜色的设置方法
  3. Netty网络编程聊天项目
  4. 读取.Properties配置文件
  5. 清掉数据_学习之大数据项目笔记第七篇【数仓模块-日志预处理篇】
  6. Car-like robot运动参数校准(图片版)
  7. 移动机器人参数校准的原由
  8. python如何读取文件建立字典_如何使用python从文本文件创建字典
  9. HTML5新增视频标签(HTML5)
  10. docker下搭建JupyterNotebook远程登录