前述

  复习一下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?

  对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。然而,假如你需要对一个有序的key集合进行遍历,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集合类的概述的更多相关文章

  1. java容器简要概述

    java中集合框架的概述 java集合类主要用于保存对象的. 常用的集合对象: Colletion接口,Collection接口是集合中的顶层容器,表示的是一组对象,它的下面有两个子接口List接口和 ...

  2. Java集合类--温习笔记

    最近面试发现自己的知识框架有好多问题.明明脑子里知道这个知识点,流程原理也都明白,可就是说不好,不知道是自己表达技能没点,还是确实是自己基础有问题.不管了,再巩固下基础知识总是没错的,反正最近空闲时间 ...

  3. 做JavaWeb开发不知Java集合类不如归家种地

    Java作为面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储.但是使用数组存储对象方面具有一些弊端,而Java 集合就像一种容器,可以动态地把多个对象的引用放入容 ...

  4. 【转载】Java集合类Array、List、Map区别和联系

    Java集合类主要分为以下三类: 第一类:Array.Arrays第二类:Collection :List.Set第三类:Map :HashMap.HashTable 一.Array , Arrays ...

  5. Java Reference简要概述

    @(Java)[Reference] Java Reference简要概述 Reference对象封装了其它对象的引用,可以和普通的对象一样操作. Java提供了四种不同类型的引用,引用级别从高到低分 ...

  6. 摘抄转载前辈们的Java集合类总结

    本文摘自 Blue Sky:http://www.cnblogs.com/hubcarl JAVA 集合类介绍和使用 类关系示意图Iterable(接口) │ └--Collection (接口) ├ ...

  7. Java集合类简单总结(重学)

    java集合类简介(重学) 一.Collection(集合).Map接口两者应该是平行关系吧. 1.Map介绍 Map是以键值(key-value)对来存放的,2个值.通过key来找到value(例: ...

  8. Java集合类中的哈希总结

    JAVA集合类中的哈希总结 目 录 1.哈希表 2.Hashtable.HashMap.ConcurrentHashMap.LinkedHashMap.TreeMap区别 3.Hashtable.Ha ...

  9. Java集合类: Set、List、Map、Queue使用场景梳理

    本文主要关注Java编程中涉及到的各种集合类,以及它们的使用场景 相关学习资料 http://files.cnblogs.com/LittleHann/java%E9%9B%86%E5%90%88%E ...

随机推荐

  1. Grokking PyTorch

    原文地址:https://github.com/Kaixhin/grokking-pytorch PyTorch is a flexible deep learning framework that ...

  2. BGP路由的手动汇总

    网络拓扑 XRV1 ========================================================== !hostname XRV1!interface Loopba ...

  3. LINQ查询表达式---------let子句

    LINQ查询表达式---------let子句 let子句创建一个范围变量来存储结果,变量被创建后,不能修改或把其他表达式的结果重新赋值给它.此范围变量可以再后续的LINQ子句中使用. class P ...

  4. CentOS 7 配置163源

    具体的操作步骤: 1.打开终端,输入su指令切换到root用户:su 2.切换到系统yum源的目录下,即:cd /etc/yum.repos.d 3.备份系统默认yum源(也可直接删除):mv Cen ...

  5. 了解Service

    多线程编程: 线程的基本用法: 1. class MyThread extends Thread{ @Override public void run() { //处理具体逻辑 } } new MyT ...

  6. Android零基础入门第66节:RecyclerView点击事件处理

    前面两期学习了RecyclerView的简单使用,并为其item添加了分割线.在实际运用中,无论是List还是Grid效果,基本都会伴随着一些点击操作,那么本期就来一起学习RecyclerView的点 ...

  7. memcached的使用一

    1.安装memcached  需要一个memcache.exe文件,打开cmd窗口,切换到可执行文件目录,执行memcache -的install命令. 2.连接服务 做测试可以打开电脑的telnet ...

  8. WPF四年,尤不足以替代WinForm

    WPF四年,尤不足以替代WinForm WPF出山已四年,作为官方内定的下一代UI系统掌门,没少露脸.但这个新掌门能否胜任,仍是众多开发者的心头之虑.通过对VisualStudio 2010的编辑器部 ...

  9. Confluence5.6.6安装和破解

    1.安装confluence 1. 软件环境说明 # 安装 jdk [root@wiki_5-- jar]# cat /etc/redhat-release CentOS Linux release ...

  10. 解读TIME_WAIT--你在网上看到的大多数帖子可能都是错误的

    由于TCP协议整个机制也非常复杂我只能尽可能的在某一条线上来说,不可能面面俱到,如果有疏漏或者对于内容有异议可以留言.谢谢大家. 查看服务器上各个状态的统计数量: netstat -ant | awk ...