Java—— 容器(集合框架)


Java 集合框架提供了一套性能优良,使用方便的接口和类,java集合框)架位于java.util包中, 所以当使用集合框架的时候需要进行导包。



一、Java集合框架体系

  1. 接口 :是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象
  2. 实现(类) :是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。
  3. 算法 :是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。
    在这里插入图片描述

二、常用接口及方法

1. Collection接口及常用方法:

Collection 接口 Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, 不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。Collection 接口存储一组不唯一,无序 的对象。

  • 查询方法
    在这里插入图片描述
  • 修改方法
    在这里插入图片描述
2. Set接口(集合)

Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素 。Set 接口存储一组唯一,无序 的对象。

  • 实现Set接口的类:
    在这里插入图片描述
  • SortedSet 接口
    在这里插入图片描述
3. List接口

List接口是一个有序 的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素 。List 接口存储一组不唯一,有序(插入顺序)的对象。

  • 实现List接口的类
    在这里插入图片描述
  • Set和List的区别
    • Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
    • Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 (实现类有HashSet,TreeSet)。
    • List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 (实现类有ArrayList,LinkedList,Vector) 。
4. Queue接口(队列)

在这里插入图片描述

  • 实现Queue接口的类
    在这里插入图片描述
5. Map接口

Map 接口存储一组键值对象,提供key(键)到value(值)的映射。不能有重复的关键字 ,每个关键字最多能够映射到一个值。声明时可以带有两个参数,Map<K, V> ,K表示关键字的类型,V表示值的类型。

  • Map接口及其子接口实现
    在这里插入图片描述
  • SortedMap 继承于 Map,使 Key 保持在升序排列。
  • 实现Map接口的常用类——HashMap, TreeMap

三、Collections工具类 —— 常用算法

1. 排序算法 sort()

在这里插入图片描述

2. 洗牌算法 shuffle()

与 sort() 算法正好相反,用于打乱元素
在这里插入图片描述

3. 常规数据处理算法

在这里插入图片描述

4. 二分查找算法binarySearch()

在这里插入图片描述

5. 寻找最值

在这里插入图片描述


四、Arrays类(数组)实用方法

  • java.utils.Arrays
    在这里插入图片描述
  • example: 数组的填充和复制
    在这里插入图片描述
  • 基于动态数组 的类型 Vector(遗留类型)、ArrayList(效率更高)

五、遍历Collection

  1. 通过 Enumeration 或 Iterator 接口遍历集合
    在这里插入图片描述
  • example:
public class Test{
 	public static void main(String[] args) {
     	List<String> list=new ArrayList<String>();
     	list.add("Hello");
     	list.add("World");
     	list.add("HAHAHAHA");
     	//  使用迭代器进行相关遍历
     	Iterator<String> ite=list.iterator();
     	while(ite.hasNext()) 
         	System.out.println(ite.next());
     }
}
  1. 增强for循环遍历集合
public class Test{
 	public static void main(String[] args) {
     	List<String> list=new ArrayList<String>();
     	list.add("Hello");
     	list.add("World");
     	list.add("HAHAHAHA");
     	//使用 For-Each 遍历 List
     	for (String str : list) {
        	System.out.println(str);
     	}
 	}
  1. 通过聚集操作遍历集合

六、Map接口及其遍历

  • 查询方法
    在这里插入图片描述
  • 修改方法
    在这里插入图片描述
  • 两个常用类HashTable(老版本)、HashMap
遍历Map
import java.util.*;
 
public class Test{
     public static void main(String[] args) {
      Map<String, String> map = new HashMap<String, String>();
      map.put("1", "value1");
      map.put("2", "value2");
      map.put("3", "value3");
 
      //第一种:普遍使用,二次取值
      System.out.println("通过Map.keySet遍历key和value:");
      for (String key : map.keySet()) {
       System.out.println("key= "+ key + " and value= " + map.get(key));
      }
 
      //第二种
      System.out.println("通过Map.entrySet使用iterator遍历key和value:");
      Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
      while (it.hasNext()) {
       Map.Entry<String, String> entry = it.next();
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
 
      //第三种:推荐,尤其是容量大时
      System.out.println("通过Map.entrySet遍历key和value");
      for (Map.Entry<String, String> entry : map.entrySet()) {
       System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
      }
 
      //第四种
      System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
      for (String v : map.values()) {
       System.out.println("value= " + v);
      }
     }
}

七、常见面试题

1. java 容器都有哪些?

常用容器的图录:
在这里插入图片描述

2. Collection 和 Collections 有什么区别?

java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式,其直接继承接口有List与Set。

Collections 则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。 ex: Collections.shuffle()

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/*
 *  集合操作的工具类
 *    Collections
 */
public class CollectionsDemo {

	public static void main(String[] args) {
		function();
		function_1();
		function_2();
	}
	/*
	 * Collections.shuffle方法
	 * 对List集合中的元素,进行随机排列
	 */
	public static void function_2(){
		List<Integer> list = new ArrayList<Integer>();
		list.add(1);
		list.add(5);
		list.add(9);
		list.add(11);
		list.add(8);
		list.add(10);
		list.add(15);
		list.add(20);	
		System.out.println(list);
		
		//调用工具类方法shuffle对集合随机排列
		Collections.shuffle(list);
		System.out.println(list);
	}
	
	/*
	 * Collections.binarySearch静态方法
	 * 对List集合进行二分搜索,方法参数,传递List集合,传递被查找的元素
	 */
	public static void function_1(){
		List<Integer> list = new ArrayList<Integer>();
		list.add(1);
		list.add(5);
		list.add(8);
		list.add(10);
		list.add(15);
		list.add(20);
		//调用工具类静态方法binarySearch
		int index = Collections.binarySearch(list, 16);
		System.out.println(index);
	}
	
	/*
	 *  Collections.sort静态方法
	 *  对于List集合,进行升序排列
	 */
	public static void function(){
		//创建List集合
		List<String> list = new ArrayList<String>();
		list.add("ewrew");
		list.add("qwesd");
		list.add("Qwesd");
		list.add("bv");
		list.add("wer");
		System.out.println(list);
		//调用集合工具类的方法sort
		Collections.sort(list);
		System.out.println(list);
	}
}

👉 Java中Collections工具类的使用

3. List、Set、Map 之间的区别是什么?

在这里插入图片描述
在这里插入图片描述

4. HashMap 和 HashTable 有什么区别?
  • HashMap把Hashtable的 contains方法 (判断Hashtable是否包含“值(value)) 去掉了,改成containsValuecontainsKey ,因为contains方法容易让人引起误解。

    HashTable则保留了contains,containsValue和containsKey三个方法,其中contains和containsValue功能相同

  • HashTable是同步的,而HashMap是非同步的,效率上逼HashTable要高。

  • HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key), 由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。

    👉 HashTable和HashMap的区别详解

    👉 HashMap和Hashtable的区别


5. 如何决定使用 HashMap 还是 TreeMap?
  • 对于在Map中插入、删除和定位元素这类操作,HashMap是最好的选择。

  • 需要对一个有序的key集合进行遍历TreeMap是更好的选择。

6. 说一下 HashMap 的实现原理?
  • HashMap概述: HashMap是基于哈希表的Map接口的非同步实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序,特别是它不保证该顺序恒久不变。

  • HashMap的数据结构: 在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

  • 当我们往Hashmap中put元素时,首先根据key的hashcode重新计算hash值,根绝hash值得到这个元素在数组中的位置(下标),如果该数组在该位置上已经存放了其他元素 (出现冲突), 那么在这个位置上的元素将以链表的形式存放,新加入的放在链头, 最先加入的放入链尾. 如果数组中该位置没有元素,就直接将该元素放到数组的该位置上。

  • 需要注意Jdk 1.8中对HashMap的实现做了优化,当链表中的节点数据超过八个之后,该链表会转为红黑树来提高查询效率,从原来的O(n)到O(logn)

7. 说一下 HashSet 的实现原理?
  • HashSet底层由HashMap实现, 跟HashMap一样,都是一个存放链表的数组。

  • HashSet的值存放于HashMap的key上,不允许有重复元素

  • HashMap的value统一为PRESENT,private static final Object PRESENT = new Object()

8. ArrayList 和 LinkedList 的区别是什么?
  • 最明显的区别是:
    ArrrayList底层的数据结构是数组,支持随机访问,
    LinkedList 的底层数据结构是双向循环链表,不支持随机访问。
  • 使用下标访问一个元素,ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)。
9. 如何实现数组Array 和 List 之间的转换?
10. ArrayList 和 Vector 的区别是什么?
  • ArrayList 和 Vector是采用 数组 方式存储数据,它允许对元素进行快速随机访问。数组的缺点是每个元素之间不能有间隔,当数组大小不满足时需要增加存储能力,就要将已经有数组的数据复制到新的更大的存储空间中。当从ArrayList的中间位置插入或者删除元素时,需要对数组进行复制、移动、代价比较高。因此,它适合随机查找和遍历,不适合插入和删除。
  • LinkedList 使用 双向链表 实现存储,按序号索引数据需要进行向前或向后遍历,但是插入数据时只需要记录本项的前后项即可,所以插入删除速度较快!
  • vector是线程(Thread)同步(Synchronized)的所以它也是线程安全的,(即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢,性能不如ArrayList)

  • Arraylist是线程异步(ASynchronized)的,是不安全的。如果不考虑到线程的安全因素,一般用Arraylist效率比较高。

  • 如果集合中的元素的数目大于目前集合数组的长度时,vector增长率为目前数组长度的100%,而arraylist 增长率为目前数组长度的50%. 如果在集合中使用数据量比较大的数据,用vector有一定的优势。

    👉 ArrayList 和 Vector 的区别

11. 数组Array 和 集合ArrayList 有何区别?
  • Array可以容纳基本类型和对象;
    而ArrayList只能容纳对象(当向集合插入不同类型的数据后,ArrayList 都会将数据当作object存储,在进行数据处理时容易出现类型不匹配的错误,使用时需要进行类型转换处理,存在装箱与拆箱操作,造成性能大量损耗的现象。)

  • Array 需要在声明时指定大小;
    而 ArrayList 大小是动态扩充与收缩的,在声明ArrayList对象时不需要指定它的长度。

    👉 数组Array、集合ArrayList、泛型List三者区别

12. 在 Queue 中 poll()和 remove()有什么区别?

poll() 和 remove() 都是移除队首元素

  • poll() 移除并获取队首元素,若成功,则返回队首元素;否则返回null;
  • remove() 移除队首元素,若移除成功,则返回true;如果移除失败(队列为空),则会抛出异常;
13. 哪些集合类是线程安全的?

线程安全: 即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性

  • Vector :就比 Arraylist 多了个同步化机制(线程安全),因为效率较低,现在已经不太建议使用。在web应用中,特别是前台页面,往往效率(页面响应速度)是优先考虑的。

  • Statck :堆栈类,先进后出,继承于Vector。

  • HashTable :就比 Hashmap 多了个线程安全。

  • Enumeration :枚举,相当于迭代器 iterator。

public class Test{
 public static void main(String[] args) {
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
    // 使用迭代器进行相关遍历
     Iterator<String> ite=list.iterator();
     while(ite.hasNext()) {
         System.out.println(ite.next());
     }
 }
}
14. 迭代器 Iterator 是什么?
  • 在Java中,有很多的数据容器,对于这些的操作有很多的共性。Java采用了迭代器来为各种容器提供了公共的操作接口。这样使得对容器的遍历操作与其具体的底层实现相隔离,达到解耦的效果。

  • 迭代器(也是一种设计模式),通常被称为轻量级对象,因为创建它的代价小。

  • 它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。

    👉 Java面试题之迭代器Iterator是什么?

15. Iterator 怎么使用?有什么特点?

Java中的Iterator功能比较简单,并且只能单向移动

  • 第一次调用Iterator的next()方法时,它返回序列的第一个元素
    注意:iterator()方法是java.lang.Iterable接口,被Collection继承。

  • 使用next()获得序列中的下一个元素。

  • 使用hasNext()检查序列中是否还有元素。

  • 使用remove()将迭代器新返回的元素删除。

Iterator是Java迭代器最简单的实现,为List设计的 ListIterator 具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。

ListIterator 👇在这里插入图片描述
下面使用 ListIterator 来对 list 进行 边遍历边添加元素 操作:在这里插入图片描述

16. Iterator 和 ListIterator 有什么区别?
  • Iterator可用来遍历Set和List集合,但是ListIterator只能用来遍历List。

  • Iterator对集合只能是前向遍历,ListIterator既可以前向也可以后向。

  • ListIterator实现了Iterator接口,并包含其他的功能,比如:增加元素,替换元素,获取前一个和后一个元素的索引,等等。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

飞天小牛肉

您的鼓励是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值