java List接口,Map接口,Set接口下的集合详解

集合

1.什么是集合?有什么用?

  • 集合实际上就是一个容器。可以来容纳其它类型的数据。

2.集合存储的数据

  • 集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,集合当中存储的都是java对象的内存地址。(或者说集合中存储的是引用。) 集合在java中本身是一个容器,是一个对象。集合中任何时候存储的都是"引用"。
  • 存储基本数据类型实际上是对基本数据类型进行包装
Collection c=new ArrayList();
c.add(1);//自动装箱Interger

3.在java中每一个不同的集合,底层会对应不同的数据结构。
往不同的集合中存储元索,等于将数据放到了不同的数据结构当中。(数据存储的结构就是数据结构)不同的数据结构,数据存储方式不同。
例如:
数组、二叉树、链表、哈希表… .

集合继承结构图

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

Collection 接口

Collection接口中的方法:

1.add(object)向集合中添加元素(boolean)

Collection c=new ArrayList();
c.add("asd");

2.size()获取集合中元素的个数(int)

Collection c=new ArrayList();
c.add("asd");
c.add(100);
System.oyut.println(c.size());
结果:2

3.clear清空集合(void)

Collection c=new ArrayList();
c.add("asd");
c.clear();
System.oyut.println(c.size());
结果:0

4.contains(Object o)判断当前集合中是否包含元素o,包含返回true ,不包含返回(boolean)
(contsains方法实现原理)

Collection c=new ArrayList();
c.add("asd");
c.contains("asd");

5.remove(object o)删除集合中的某个元素。(boolean)

Collection c=new ArrayList();
c.remove("asd");

6.isEmpty()郸断该集合中元素的个数是否为0(boolean)

Collection c=new ArrayList();
c.isEmpty();

7.toArray()调用这个方法可以把集合转换成数组。(0bject[ ] )

Collection c=new ArrayList();
Object[] oj=c.toArray();

List接口

List集合存储元秦特点:

有序可重复

  • 有序:List集合中的元素有下标。从0开始,以1递增。
  • 可重复:存储一个1,还可以再存储1.

List接口常用方法:

1.add(int index,0bject element)添加元素 (void)

List l=new ArrayList();
l.add(1,"a");
l.add(2,"b");

2.get(int index)获取当前下标元素(Object)

List l=new ArrayList();
l.add(0,"a");
l.add(1,"b");
l.get(0);
结果:a
  1. indexOf(object o)获取元素第一次出现的下标(int)
List l=new ArrayList();
l.add(0,"a");
l.add(1,"a");
l.indexOf("a");
结果:0
  1. lastIndex0f(object o)获取元素最后一次出现的下标(int)
List l=new ArrayList();
l.add(0,"a");
l.add(1,"a");
l.latIndexOf("a");
结果:1

5.remove(int index)删除当前下标元素(Object)

List l=new ArrayList();
l.add(0,"a");
l.remove(0);
  1. set(int index, object element)修改指定下标元素(Object)
List l=new ArrayList();
l.add(0,"a");
l.set(0,"b");

集合的遍历

使用递归对集合遍历和删除

ArrayList集合

ArrayList集合底层采用了数组数据结构
ArrayList集合是非线程安全的

  • 1、ArrayList集合初始化容里是10
  • 2、ArrayList集合底层是Object类型的数组Object[]
  • 3、扩容到原容里的1.5倍。
int newCapacity = ArraysSupport .newLength(oldCapacity ,
	minCapacity - oldCapacity,
	oldcapacity >>1)

右移一位=原始值的一半(即扩大了1.5倍)=增加的量
新容量=原容量+增加的量=10+5=10*1.5=15

  • 4、建议给定一个预估计的初始化容里,减少数组的扩容次数,这是ArrayList集合比较重要的优化策略。
  • 5、数组的优点:检索效率比较高
  • 6:、教组的缺点:随机增删元素效率比较低。

LinkedList集合

LinkedList集合底层采用了双向链表数据结构
节点是双向链表中基本的单元。每一个节点Node都有三个属性;

  • 存储的数据。
  • 下一个节点的内存地址。
  • 上一个节点的内存地址。

在这里插入图片描述
链表的优点:
由于链表上的元素在空间存储上内存地址不连续。所以随机增删元素的时候不会有大量元素位移,因此随机增删效率较高。
链表的缺点:
不能通过数学表达式计算被查找元素的内存地址,每一次查找都是从头节点开始遍历,直到找到为止。所以LinkedList集合检索/查找的效率较低。

注意:ArrayList之所以检索效率比较高,不是单纯因为下标的原因。是因为底层数组发挥的作用。linkedList集合照样有下标,但是检索,查找某个元素的时候只能从头节点开始,因此效率比较低。

Vector集合

Vector集合底层采用了数组数据结构

1、初始化容量: 10
2、怎么扩容的?
扩容之后是原容量的2倍。10–>20

3.Vector中所有的方法都是线程同步的,都带有synchronized关键字,是线程安全的。效率比较低。

5.线程不安全集合转换成线程安全集合
使用集合工具类:java.util.collections;

List l=new ArrayList();
Collections.synchronized(l);

Set集合

HashSet集合

实际上HashSet集合在new的时候,底层实际上new了—个HashMap集合
向HashSet集合中存储元素,实际上是存储到HashMap集合(哈希表数据结构)中了。

  • Hashset集合初始化容里16
  • 初始化容里建议是2的倍数。
  • 扩容:扩容之后是原容量的2倍。

SortedSet接口

SortedSet集合存储元素的特点:由于继承了Set集合,所以它的特点也是无序不可重复,但是放在SortedSet集合中的元素可以按照大小顺序自动排序.

TreeSet集合
  • 1、TreeSet集合底层实际上是一个TreeMap、 TreeMap集合底层是一个二叉树。
  • 2、放到TreeSet集合中的元素,等同于放到TreeMap集合key部分了。
  • 3、TreeSet集合中的元素:无序不可重复,但是可以按照元素的大小顺序自动排序。称为:可排序集合。
Set<Integer> s=new TreeSet();
s.add(1);
s.add(5);
s.add(2);
s.add(10);
for(Integer i:s){
	System.out.println(i);
}
结果:
	1
	2
	5
	10

自定义类型的排序
TreeSet集合自定义类型的排序

Map接口

  • 1、Map和collection没有继承关系。
  • 2、Nap集合以key和value的方式存储数据:键值对

key和value都是引用数据类型。
key和value都是存储对象的内存地址。
key起到主导的地位,value是key的一个附属品。

Map集合的遍历

Map集合的遍历

Map接口中接口的方法:

  1. put( key, value)向Nap集合中添加键值对
Map m=new HashMap();
m.put(1,"a");
  1. get(object key)通过key获取value
Map m=new HashMap();
m.put(1,"a");
m.get(1);
  1. clear()清空Map集合(void )
Map m=new HashMap();
m.clear();
  1. containsKey(object key)判断Map中是否包含某个key(boolean )
Map m=new HashMap();
m.put(1,"a");
m.containsKey(1);
结果:true
  1. containsvalue(object value)判断Map中是否包含某个value(boolean )
Map m=new HashMap();
m.put(1,"a");
m.containsValue("a");
结果:true
  1. isEmpty()判断Map集合中元素个数是否为e(boolean )
Map m=new HashMap();
m.isEmpty();
  1. keySet()获取Map集合所有的key (所有的键是一个set集合)(Set )
Map m=new HashMap();
m.put(1,"a");
m.put(2,"a");
Set s=m.keySet();
System.out.println(s);
结果:[1,2]
  1. remove( object key)通过key删除键值对
Map m=new HashMap();
m.put(1,"a");
m.remove(1);

9.size()获取Map集合中键值对的个数。(int )

Map m=new HashMap();
m.size();
  1. values()获取Map集合中所有的value ,返回一个collection(collection)
Map m=new HashMap();
m.put(1,"a");
m.put(2,"b");
Collection<String> c=m.values();;
System.out.println(c);
结果:["a","b"]

11.entrySet()|将Map集合转换威set集合(Set<Map.Entry<K,V>> )

Map m=new HashMap();
m.put(1,"a");
m.put(2,"b");
Set<Map.Entry<Intrger,String>> s=m.entrySet();
System.out.println(s);
结果:
	[1=a,2=b]

Map.Entry是Map中的静态内部类

HashMap

HashMap集合底层是哈希表/散列表的数据结构。

如果哈希表单向链表中元素超过8个,单向链表会变成红黑树数据结构。当红黑树上的节点数里小于6时,会重新把红黑树变成单向链表数据结构。

1、哈希表是一个怎样的数据结构呢?

  • 哈希表是一个一维数组和单向链表的结合体。这个数组中每一个元素是一个单向链表。

1.数组:在查询方面效率很高,随机增删方面效率很低。
2.单向链表:在随机增删方面效率较高,在查询方面效率很低。
3.哈希表将以上的两种数据结构融合在一起,充分发挥它们各自的优点。

为什么哈希表的随机增删,以及查询效率都很高?

  • 增删是在链表上完成。
  • 查询也不需要都扫描,只需要部分扫描。

2.HashMNap结构图
在这里插入图片描述
3、HashMNap集合底层的源代码;

public class HashMap{
	Node<K,V>[ ] tabLe;
//静态的内部类HashMap.Node
	static class Node<K,V>{
		final int hash;//哈希值(哈希值是key的hashCode()方法的
		//执行结果。hash值通过哈希函数/算法,可以计算出key值所对应的下标
		final K key; //存储到Map集合中的那个key
		v value;//存储到Map集合中的那个vaLue
		Node<K ,V> next;//下一个节点的内存地址。
	}
}

4.HashMap集合的key部分特点:

  • 无序
    因为不一定挂到单向链表上哪个位置。
  • 不可重复。
    equals方法来保证HashMap集合的key不可重复。如果key重复了,value会覆盖。

HashMap集合的key部分允许null,但只能有一个null值

5.HashMNap实现put和get方法的底层原理
put()方法

  • 先将看k,v封装到node对象中去,通过HashCode()方法得出hash值,再通过哈希算法将得出hash值转换成数组的下标,下标位置上如果没有任何元素,就把node对象直接添加,如果对应的下标上有链表,此时会拿着要添加node对象中的key和链表中的key一 一比较(equals),如何所有的equals方法的结果都是false,那么将这个节点放到链表的最后。如何有一个返回true,则覆盖key所对应的value

get()方法

  • 先调用k的hashCode0方法得出哈希值,通过哈希算法转换成数组下标,通过数组下标快速定位到某个位置上,如果这个位置上什么也没有,返回null。如果这个位置上有单向链表,那么会拿着参数k和单向链表上的每个节点中的k进行equals,如果所有equals方法返回false,那么get方法返回null,只要其中有一个节点的k和参数kequals的时候返回true,那么此时这个节点的value就是我们要找的value , get方法最终返回这个要找的value.

8、HashMap集合的默认初始化容量

HashMap集合的默认初始化容量是16,默认加载因子是0.75
这个默认加载因子是当HashMap集合底层数组的容量达到75%的时候,数组开始扩容。

重点,记住:HashMap集合初始化容量必须是2的倍数,这是因为达到散列均匀,为了提高HashMap集合的存取效率,所必须的。

HashTable集合

Hashtable集合底层是哈希表数据结构,

  • 1.是线程安全的·其中所有的方法都带有synchronized关键字:效率较低,现在使用较少了,因为空制线程安全有其它更好的方案。
  • 2.Hashtable的约key和value不允许null
  • 3.Hashtable集合初始化容量11
  • 4.Hashtable集合扩容是:原容里*2+1
Properties集合
  • Properties是一个Map集合,继承Hashtable集合。
  • Properties的key和value都是String类型。
  • Properties被称为属性类对象。
  • Properties是线程安全的。

Properties的存取方法

1.setProperty(“key”,“vaule”);

Properties p=new Properties();
p.serProperties("name","zhangsan");

2.getProperty(“key”);(通过key获取value)

p.getProperty("name");

SortedMap接口

SortedMap集合的key存储元素的特点:
无序不可重复的,另外放在SortedMap集合key部分的元素会自动按照大小顺序排序,称为可排序的集合.

TreeMap集合

TreeMap集合底层的数据结构是一个二叉树
自平衡二叉树
自定义类型的排序

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值