Java集合类的概述
前述
复习一下Java中的集合类,是面试笔试中常考察的一个点,特地做的整理。
什么是集合类?
集合类,也叫容器类。Java集合类可以用来存储数量庞大的对象。
我们和数组进行对比:
数组:存储基本数据类型,数据类型单一,长度固定,不能动态增大容量。
集合:存储的即可是基本类型的值,也可以是对象,可以存储多种数据类型,长度可变,可以动态增大容量。
Java集合类的体系
Java集合类主要有两个接口派生而出:Collection和Map。即集合类都是实现的这两个接口。我们在实际编程中经常使用的有 List、Set、Queue(这些是实现的 Collection 接口)HashMap、TreeMap、HashTable(这些实现的 Map 接口)
Collection接口结构
Collection 接口位于 Java.util 包下,是一个父接口, List、Set、Queue 都是实现的 Collection 接口。Collection 做为父接口提供一些操作集合类的方法,因此它的子接口也有这些方法。
Collection 接口不能被实例化,并且在实际的编程过程中几乎不会使用它进行数据的存储。

Map接口结构
Map 接口实现的是键值对的存储,类似 python 中的 dict。
Map中比较常见的是 HashMap、TreeMap、Hashtable 类。

Set接口
Set 接口继承自 Collection 接口,Collection 接口有的方法 Set 接口中也有。
Set 接口自身的特性:
- 不允许重复元素
- 不区分先后顺序(无序)
- 允许值是 null
Set 接口有两个比较常用的具体实现,HashSet、TreeSet。下面分别说一下这两个集合类。
HashSet
主要特点是快速查找元素。HashSet 是基于 Hash 算法来实现的,在每次添加新的对象的时候,会根据散列码来判断对象是否重复,散列码的获取是通过 Object 的 hashCode() 来实现的。同样 HashSet 也是无序的。
import java.util.*;
/**
* @author jyroy
* HashSet使用
*/
public class HashSetDemo {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
hashSet.add("Tom");
hashSet.add("Jack");
hashSet.add("Roy");
System.out.println(hashSet);
}
}

当有重复元素添加时,结果如下
import java.util.*;
/**
* @author jyroy
* HashSet使用
*/
public class HashSetDemo {
public static void main(String[] args) {
HashSet hashSet = new HashSet();
hashSet.add("Tom");
hashSet.add("Tom");
hashSet.add("Jack");
hashSet.add("Roy");
System.out.println(hashSet);
}
}

TreeSet
主要特点是会进行自然排序,同样不能重复。参考如下的代码,可以看出 TreeSet 把原本无序的值进行了重新排序,依据的就是自然排序。
import java.util.*;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
treeSet.add("Tom");
treeSet.add("Jack");
treeSet.add("Roy");
System.out.println(treeSet);
}
}

然而,在实际开发中很多时候我们很多时候遵循的不是自然排序,而是有自己定义的排序规则,我们要做的就是新建一个类并且实现 compareTo() 方法。
下面的代码实现的是根据年龄由小到大进行排序,比较简单,一看就懂的代码。
import java.util.TreeSet;
class Person implements Comparable{
public String name;
public int age;
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Object o) {
Person person = (Person) o;
if(this.age < person.age) {
return -1;
}else if(this.age > person.age) {
return 1;
}else {
return 0;
}
}
}
public class TreeSetDemoCompareto {
public static void main(String[] args) {
TreeSet treeSet = new TreeSet();
Person person1 = new Person();
Person person2 = new Person();
Person person3 = new Person();
person1.name = "Tom";
person1.age = 20;
person2.name = "Jack";
person2.age = 21;
person3.name = "Roy";
person3.age = 22;
treeSet.add(person1);
treeSet.add(person2);
treeSet.add(person3);
System.out.println(treeSet);
}
}

List接口
List 接口继承了 Collection 接口,Collection 接口有的方法 List 中也有。
List 接口自身的特性:
- 利用数组方式提供了获取、修改、删除的功能。
- 可以通过方法来获取元素的位置。
- 允许重复元素的有序集合。
List 接口有两个比较常用的具体实现,ArrayList、Vector、LinkedList。下面分别说一下这两个集合类。
ArrayList
ArrayList 本身是通过数组的方式实现的,大小可以随着对象的增加而增加。查询效率比较高,增加、删除的效率比较低,这也是数组的一种特性。非线程安全的。而且是有序的。
import java.util.*;
/**
* @author jyroy
*/
public class ArrayListDemo {
public static void main(String[] args) {
List arrayList = new ArrayList();
arrayList.add("Tom");
arrayList.add("Jack");
arrayList.add("Roy");
System.out.println(arrayList);
}
}

Vector
Vector 和 ArrayList 是相似的,都是通过数组来实现的。
最大的区别就是线程安全方面。Vector 是线程安全的,同步的,Vector类对集合的元素操作时都加了synchronized,保证线程安全。而 ArrayList 是非线程安全的。也是因为线程安全的问题,ArrayList 的查询效率比 Vector 要高。
另外一个区别是在扩容方面,Vector默认扩容是增长一倍的容量,Arraylist是增长50%+1的容量。
Vector与ArrayList的remove,add(index,obj)方法都会导致内部数组进行数据拷贝的操作,这样在大数据量时,可能会影响效率。
import java.util.*;
public class VectorDemo {
public static void main(String[] args) {
List vectorList = new Vector();
vectorList.add("Roy");
vectorList.add("Tom");
vectorList.add("Jack");
System.out.println(vectorList);
}
}

LinkedList
LinkedList 和 ArrayList、Vector相比,在方法的使用上都是相似的。
LinkedList 是基于双向链表的,比较利于对象的增加和删除操作,但是对查询的支持不够好,这是链表的特点。 LinkedList 同样是线程不安全的。
import java.util.*;
public class LinkedListDemo {
public static void main(String[] args) {
List linkedList = new LinkedList();
linkedList.add("Roy");
linkedList.add("Jack");
linkedList.remove(0);
linkedList.add("Tom");
System.out.println(linkedList);
}
}

Queue接口
Queue 是 Collection 的子接口,中文称为队列,特性就是先进先出,先进入队列的对象,在进行删除的时候最先被删除。所有的删除操作都是在队首进行的,所有的插入操作都是在队尾进行的。
import java.util.*;
public class QueueDemo {
public static void main(String[] args) {
Queue queue = new LinkedList();
queue.add("Tom");
queue.add("Roy");
System.out.println(queue.poll()); //出队列操作
queue.add("Jack");
System.out.println(queue);
}
}

HashMap
HashMap 是基于散列表的 Map 接口的实现类,线程不安全。
散列表是通过关键码值(Key value)而直接进行访问的数据结构。它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
当HashMap中的元素个数超过数组大小(数组总大小length,不是数组中个数size)*loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75,这是一个折中的取值。也就是说,默认情况下,数组大小为16,那么当HashMap中元素个数超过16*0.75=12(这个值就是代码中的threshold值,也叫做临界值)的时候,就把数组的大小扩展为 2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置。
下面的代码实现了获取key为 2 的元素的 value。
import java.util.*;
public class HashMapDemo {
public static void main(String[] args) {
HashMap hashMap = new HashMap();
hashMap.put(1, "Tom");
hashMap.put(2, "Jack");
hashMap.put(3, "Roy");
System.out.println(hashMap.get(2));
System.out.println(hashMap);
}
}

TreeMap
TreeMap 是根据红黑树算法实现的,TreeMap最大的特性就是支持自然排序。从下面的代码中也可以非常清晰的看出 TreeMap 利用 key 值进行了自然排序。
红黑树(Red Black Tree) 是一种自平衡二叉查找树,是在计算机科学中用到的一种数据结构,典型的用途是实现关联数组。
import java.util.*;
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap treeMap = new TreeMap();
treeMap.put("2", "Tom");
treeMap.put("1", "Roy");
treeMap.put("3", "Jack");
System.out.println(treeMap);
}
}

HashTable
HashTable 和 HashMap 是基本一致的。
最大的区别是 HashTable 是线程安全的,HashMap 不是。
import java.util.*;
public class HashTableDemo {
public static void main(String[] args) {
Hashtable hashtable = new Hashtable();
hashtable.put("2", "Tom");
hashtable.put("1", "Roy");
hashtable.put("3", "Jack");
System.out.println(hashtable);
}
}

常见问题
这些问题是在其他一些大佬的博客中看到,做了一个整理,都是 Java 集合类的问题。
1. ArrayList和LinkedList的特点和区别?
ArrayList: 底层用数组实现,由于数组可以通过下标直接访问指定索引的元素,因此,ArrayList通过索引查询元素非常快。但由于插入和删除元素时都会进行数组的重新排列,因此,ArrayList的插入和删除操作比较慢。
LinkedList:底层用链表实现,由于链表没有具体的下标,因此,访问某个索引的节点时需要遍历该节点前面的所有元素,速度比较慢。由于插入和删除元素时只需要更新相应元素的指针(或引用),不用重新排列元素,因此,LinkedList对插入和删除操作比较快。
LinkedList 比 ArrayList消耗更多的内存,因为 LinkedList 中的每个节点存储了前后节点的引用。
2. ArrayList和Vector的区别?
ArrayList非线程安全,Vector线程安全。在扩容时,ArrayList默认扩容当前容量的50%,但Vector默认扩容当前容量的100%。
3. HashSet和TreeSet的区别?
HashSet基于HashMap,用键来存放HashSet的值,由于HashMap的键不能重复,因此,HashSet的值也不会重复,这是集合的一个特点。
TreeSet基于TreeMap,也是用键来存放TreeSet的值。TreeMap的底层实现是红黑树,其根据键排序,可以得到排好序的数据。
4. HashMap和HashTable的区别?
HashMap非线程安全,HashTable线程安全。
HashMap可以允许一个null键和多个null值,但HashTable不允许,会出现NullPointerException。
5. HashMap和TreeMap的区别?
HashMap中存放的键是随机的,具有较快的访问和存取速度,TreeMap中的键是按照自然排序排好的。
6. Java集合框架的基础接口有哪些?
Collection 和 Map ,一个元素集合,一个是键值对集合; 其中 List、Set、Queue 接口继承了 Collection 接口,一个是有序元素集合,一个是无序元素集合,一个是队列; 而 ArrayList 和 LinkedList 实现了 List 接口,HashSet 实现了 Set 接口,这几个都比较常用; HashMap、HashTable、TreeMap 实现了 Map 接口,并且 HashTable 是线程安全的,HashMap 是非线程安全的,但是 HashMap 性能更好。
7. 如何决定选用HashMap还是TreeMap?
8. 哪些集合类提供对元素的随机访问?
ArrayList、HashMap、TreeMap和HashTable类提供对元素的随机访问。
9. Array和ArrayList有何区别?什么时候更适合用Array?
Array可以容纳基本类型和对象,而ArrayList只能容纳对象。
Array是指定大小的,而ArrayList大小是根据内容自动扩张的。
Array没有提供ArrayList那么多功能,比如addAll、removeAll和iterator等。尽管ArrayList明显是更好的选择,但也有些时候Array比较好用。
(1)如果列表的大小已经指定,大部分情况下是存储和遍历它们。
(2)对于遍历基本数据类型,尽管Collections使用自动装箱来减轻编码任务,在指定大小的基本类型的列表上工作也会变得很慢。
(3)如果你要使用多维数组,使用[][]比List<List<>>更容易。
Java集合类的概述的更多相关文章
- java容器简要概述
java中集合框架的概述 java集合类主要用于保存对象的. 常用的集合对象: Colletion接口,Collection接口是集合中的顶层容器,表示的是一组对象,它的下面有两个子接口List接口和 ...
- Java集合类--温习笔记
最近面试发现自己的知识框架有好多问题.明明脑子里知道这个知识点,流程原理也都明白,可就是说不好,不知道是自己表达技能没点,还是确实是自己基础有问题.不管了,再巩固下基础知识总是没错的,反正最近空闲时间 ...
- 做JavaWeb开发不知Java集合类不如归家种地
Java作为面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储.但是使用数组存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容 ...
- 【转载】Java集合类Array、List、Map区别和联系
Java集合类主要分为以下三类: 第一类:Array.Arrays第二类:Collection :List.Set第三类:Map :HashMap.HashTable 一.Array , Arrays ...
- Java Reference简要概述
@(Java)[Reference] Java Reference简要概述 Reference对象封装了其它对象的引用,可以和普通的对象一样操作. Java提供了四种不同类型的引用,引用级别从高到低分 ...
- 摘抄转载前辈们的Java集合类总结
本文摘自 Blue Sky:http://www.cnblogs.com/hubcarl JAVA 集合类介绍和使用 类关系示意图Iterable(接口) │ └--Collection (接口) ├ ...
- Java集合类简单总结(重学)
java集合类简介(重学) 一.Collection(集合).Map接口两者应该是平行关系吧. 1.Map介绍 Map是以键值(key-value)对来存放的,2个值.通过key来找到value(例: ...
- Java集合类中的哈希总结
JAVA集合类中的哈希总结 目 录 1.哈希表 2.Hashtable.HashMap.ConcurrentHashMap.LinkedHashMap.TreeMap区别 3.Hashtable.Ha ...
- Java集合类: Set、List、Map、Queue使用场景梳理
本文主要关注Java编程中涉及到的各种集合类,以及它们的使用场景 相关学习资料 http://files.cnblogs.com/LittleHann/java%E9%9B%86%E5%90%88%E ...
随机推荐
- 怎样解决python dataframe loc,iloc循环处理速度很慢的问题
怎样解决python dataframe loc,iloc循环处理速度很慢的问题 1.问题说明 最近用DataFrame做大数据 处理,发现处理速度特别慢,追究原因,发现是循环处理时,loc,iloc ...
- 基于开源软件构建高性能集群NAS系统,包括负载均衡(刘爱贵)
大数据时代的到来已经不可阻挡,面对数据的爆炸式增长,尤其是半结构化数据和非结构化数据,NoSQL存储系统和分布式文件系统成为了技术浪潮,得到了长足的发展.非结构化数据目前呈现更加快速的增长趋势,IDC ...
- 使用内核对象Mutex可以防止同一个进程运行两次
用互斥法实现防止程序重复运行,使用内核对象Mutex可以防止同一个进程运行两次.注意:是名称相同的进程,而不是exe,因为exe程序可以改名. using System.Threading; publ ...
- TThread类详解
TThread是一个抽象类,可以创建几个独立的线程.类关系 TObject在一个多线程的应用程序中创建一个TThread的后子类代表一个线程.每一新子类的TThread对象的实例是一个新的线程.从TT ...
- Linux之文件的压缩与解压缩
压缩格式 .zip,.rar,.7z,.tar,.gz,.xz,.bz2,.tar.gz,.tar.xz,.tar.bz2,其中,形如*.tar.gz为tar打包,gz压缩的文件 zip压缩打包程序 ...
- Oracle emca on linux
http://blog.csdn.net/haibusuanyun/article/details/16338591 bash-3.2$ lsnrctl status LSNRCTL for Lin ...
- Laravel:php artisan key:generate三种报错解决方案,修改默认PHP版本(宝塔面板)
为了兼容N多个网站,服务器上有3个PHP版本5.3/5.6/7.2.宝塔默认为5.3,但是laravel5.7并不支持,所以在创建线上 .env 环境配置文件,初始化应用配置时候报错了. cp .en ...
- 第二章 在Linux上部署.net core
项目目标部署环境:CentOS 7+ 项目技术点:.netcore2.0 + Autofac +webAPI + NHibernate5.1 + mysql5.6 + nginx 开源地址:https ...
- spring cloud 系列第2篇 —— eureka 高可用注册中心的搭建 (F版本)
源码仓库地址:https://github.com/heibaiying/spring-samples-for-all 一.项目结构 eureka-server为服务注册中心,负责服务的管理: eur ...
- 以实现MongoDB副本集状态的监控为例,看Telegraf系统中Exec输入插件如何编写部署
既有的Telegraf 关于MongoDB的输入插件很难实现对副本集节点状态的监控,副本集节点状态有 PRIMARY.SECONDARY.RECOVERYING.ARBITER 等.现在我们尝试通过 ...