集合总结

2021/5/25 18:18:02

本文主要是介绍集合总结,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

集合:
1.集合概述
1.1什么是集合?有什么用?
数组其实就是一个集合,集合实际就是一个容器,可以来容纳其它类型的数据
集合是一个容器,一个载体,可以一次容纳多个对象
1.2
集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,集合当中存储的都是java对象的内存地址。(或者说集合中存储的是引用。)
list.add(100);//自动装箱 Integer
注意:
集合在java中本身是一个容器,是一个对象
集合中任何时候存储的都是“引用”。
1.3在java中的集合分为两大类
一类是单个方法存储元素
单个方法存储元素,这一类集合中超级父接口:java.util.Collection;
一类是以键值对的方式存储元素
以键值对的方式存储元素,这一集合中超级父接口:java.util.Map;
1.4集合在java JDK那个包下?
所以的集合类和集合接口都在java.util包下
所有集合继承Iterable的含义是 所有集合都是可迭代的,因为Inerable里面有一个Iterator()方法
迭代就是遍历,可迭代就是可遍历的
迭代里的方法hasNext,next,remove

list集合:有序可重复,存进的元素有下标 有序是:存进来什么取出来是什么。有序因为list集合都有下标,可重复,下标从0开始以1递增

set集合:存储元素特点:无序不可重复,set集合中的元素没有下标,set集合中的元素不能重复

list中要学到的实现类:
ArrayList集合底层采用数组这种数据结构,ArrayList集合是非线程安全的。
LinkedList集合底层采用双向链表数据结构
Vector集合底层采用数组这种数据结构,Vector集合是线程安全的,vector里面所有方法都有sychronized关键字修饰,所以线程安全,但是效率较低,现在保证线程安全有别的方案,所以Vector使用较少了

set集合中的实现类:
HashSet:
实际上HashSet集合在new的时候 底层实际上new了一个HashMap集合,向HashSet集合中存储元素实际上存储到HashMap中了,HashMap集合是一个哈希表数据结构
TreeSet集合底层实际上是TreeMap,newTreeSet集合的时候,底层实际上new了一个TreeMap集合,往TreeSet集合放数据实际上是将数据放在了TreeMap中了.
TreeMap集合底层采用二叉树数据结构

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

Map集合:
1.Map集合和Collection没有关系
2.Map集合以key和value的这种键值对的方法存储元素
3.key和value都存储java对象的内存地址
4.所以Map集合的Key都是无序不可重复的,Map集合的kay和Set集合存储元素特点相同

HashMap集合底层是哈希表数据结构,是非线程安全的

Hashtable集合底层也是哈希表数据结构,是线程安全的其中所有的方法都带有synchronized关键字,效率较低,现在使用较少,因为控制线程安全有其他更好的方法

SortedMap集合的Key存储元素的特点:首先 是无序不可重复的,另外放在SortedMap集合Key部分的元素会自动按照大小顺序排序,称为可排序的集合
TreeMap 集合底层的数据结构是一个二叉树

Properties 是线程安全的因为继承Hashtable,另外Properties存储元素的时候也是采用key和value的形式存储,并且key和value只支持String类型.不支持其他类型
Properties被称为属性类

总结(实现类)
1.ArrayList:底层是数组
2.LinkedList:底层是双向列表
3.Vector:底层是数组,线程安全,效率较低,使用较少
4.HashSet:底层是HashMap,放到HashSet集合中的元素等同于HashMap集合Key部分
5.TreeSet:底层是TreeMap,放到TreeSet集合中的元素等同于放到TreeMap集合key部分
6.HashMap:底层是哈希表
7.Hashtable:底层也是哈希表,只不过线程安全,效率较低,使用较少
8.Properties:是线程安全的,并且kay和value只能存储字符串String
9.TreeMap:底层是二叉树,TreeMap集合的key可以自动按照大小顺序排序

1.List 集合存储元素的特点
有序可重复,存进去的每一个元素都有下标
2.set(Map) 集合存储元素的特点
无序不可重复 set集合中的元素没有下标
3.SortedSet(SortedMap) 集合存储元素的特点
首先是无序不可重复的 但是SortedSet集合中的元素可排序的
4.Map集合的key就是一个Set集合往set集合放数据数据,实际放到了Map集合的key部分

contains :判断一个集合中是否包含这个元素

remove :删除对象

list

哈希表数据结构
HashMap集合(是非线程安全的,初始化容量为16):
1.HashMap集合底层是哈希表/散列表的数据结构
2.哈希表是一个怎样的数据结构呢?
哈希表是一个数组和单向列表的结合体
数组:在查询方面效率较高,在随机增删方面效率较低
单项链表:在随机增删方面较高,在查询方面效率较低
哈希表将以上两种数据结构融合在一起,充分发挥它们的各自的特点
3.HashMap集合底层源代码:

  public class HashMap{
  	//HashMap底层实际上就是一个数组(一堆数组)
  	Node<k,v>[] = table;
  	//静态的内部类HashMap,Node
  	static class Node<k,v>{
  		final int hash; //哈希值(哈希值是key的hashcode()方法的执行结构.hash值通过哈希函数/算法,可以转化为数组的下标)
  		final k key;  //存储到map集合的那个key
  		final value;  //存储到map集合中的那个value
  		Node<k,v> next; //下一个节点的内存地址
  	}
  }

哈希表/散列表:一堆数组,这个数组中每一个元素是一个单向链表
4.主要掌握的是:
map.put(k,v)
v=map.get(k)
以上这两个方法的实现原理,是必须掌握的
map.put(k,v)的实现原理:
第一步:先将 k,v 封装到Node对象当中
第二步:底层会调用key的hashcode()方法得出hash值,然后通过哈希函数/哈希算法,将hash值转化为数组的下标,下标位置上如果没有
任何元素就把Node添加到这个位置上,如果下标对应的位置上有链表,此时会拿着key和链表上每一个节点中的k进行equals,如果所有的
equlals返回的都是false那么这个新节点将会添加到链表的末尾,如果其中的一个equals返回true,那么这个节点的value将会被覆盖
v=map.get(k)的实现原理:
先调用key的hashCode()方法得出hash值,通过哈希算法转化为数组下标,通过数组下标快速定位到某个位置上,如果这个位置上什么也
没有返回null,如果这个位置上有单项链表,那么就会拿着参数的k和单项链表上的每一个节点中的k进行equals,如果所有的equals
方法返回false,那么get方法返回null;只要其中有一个节点的k和参数k返回true,那么此时这个节点的value就是我们要找的value
get方法最终返回这个要找的value

为啥哈希表的随机增删和查询都高
增删是在链表上完成的
查询也不需要进行扫描,只需要部分扫描

HashMap集合的key 会先后调用两个方法:一个方法是hashCode() 一个方法是equals() 那么这两个方法都需要重写

5.HashMap集合的key部分的特点
无序不可重复
为什么无序?
因为不一定挂到那个单项列表中
不可重复是怎么保证的?
底层调用equals()方法来保证hashmap集合的key不可重复,如果key重复了 value会覆盖

放在HashMap集合Key部分的元素其实就是放在Hashset集合当中

同一个链表上所有节点的hash相同,因为它们的下标相同,但同一个链表上k和k的equlas方法肯定返回的是false 都不相同

6.重点:放在HashMap集合key部分的元素,以及放在HashSet集合中的元素,需要同时重写hashcode和equal方法

在JDK8之后,如果哈希单向列表中元素超过8个,单向链表的数据结构会变成红黑树的数据结构;
当红黑上的节点数量小于6时,会重新把红黑树变成单项列表数据结构
这种方式也是为了提高检索的效率,二叉树的检索会再次缩小检索范围

对于哈希表数据结构来说:如果o1和o2的hash值相同,一定放在同一个单项链表上,如果o1和o2的值不同,但由于哈希算法执行结束之后转化的数组下标可能相同,此时会发生"哈希碰撞".

HashMap的扩容:一次扩容之后的容量是原容量的2倍.

HashMap集合的key允许为null吗?
允许但是要注意:HashMap集合的key null值只能有一个

{
   Map map = new HashMap();
     //HashMap集合的key允许为null
   map.put(null,null);
   System.out.println(map.size()); //1
     //key重复的话value是覆盖
   map.put(null,100);
   System.out.println(map.size());//1
   //通过key获取value
   System.out.println(map.get(null));//100
}

Hashtable的Key可以为null吗?
Hashtable 的Key和value都是不可以为null的
Hashtable 方法都带有synchronized:是线程安全的

Hashtable 和 HashMap 一样底层都是哈希表

Hashtable :初始化容量为11,默认加载因子为0.75f,扩容方式:扩容后的容量=原容量*2+1

{
	Map map = new Hashtable();
	map.put(null,"111");
	map.put(1,null);


}

Properties
目前只需要掌握properties属性类对象相关方法即可

Properties 是一个Map集合,继承Hashtable Properties的key和value都是String类型

Properties 被称为属性类对象
Properties 是线程安全的

 {  创建一个properties对象
  Properties pro = new Properties();
  //需要掌握properties的两个方法,一个存,一个取
  pro.setProperty("username","root");


  //通过key获取value
 String username = pro.getProperty("username");

 System.out.println(username);//root

 }

HashSet集合 初始化容量为16 初始化容量建议为2的倍数
HashSet的扩容:一次扩容之后的容量是原容量的2倍.

1.TreeSet 集合底层实际上是TreeMap
2.TreeMap 集合底层的一个二叉树
3.放到TreeSet集合中的元素等同于放到TreeMap集合key部分
4.TreeSet集合中的元素,无序不可重复,但是可以按照元素的大小顺序自动排序

{
	//创建一个TreeSet集合
	TreeSet<String> ts = new TreeSet();
	//添加String
	ts.add("zhangsan");
	ts.add("lisi");
	ts.add("wangwu");
	ts.add("wangliu");
	//遍历
	for(String s:ts){
		//按照字典升序排序
		System.out.println(s);
	}

}

一次读取一个字节byte,这样内存和硬盘交互太频繁,基本数时间都浪费在交互上了

能不能一次读取多个字节呢?

//一次最多读取b.lengeh个字节,减少硬盘和内存的交互,提高程序的执行效率,往byte[]数组当中读

{
  FileInputStream fis = null;

  //相对路径是当前所在的位置作为起点开始找
  //IDEA默认的当前路径在哪里?工程project的根就是IDEA的当前路径
  
  fis = new FileInputStream("");
}

TreeSet集合/TreeMap集合是自平衡二叉树:
遵循左小右大原则存放,存放时要依靠左小右大原则,
所以这个存放的时候要进行比较

 遍历二叉树有三种:
  1.前序遍历 根左右
  2.中序遍历 左根右
  3.后序遍历 左右根
  注意:前中后说的是根的位置
    根在前面是前序,根在中间是中序,根在后面是后序

TreeSet集合/TreeMap集合采用的是:中序遍历方式
Iterator迭代器采用的是中序遍历方式 左根右

TreeSet集合中元素可排序的两种方法:使用比较器的方法
最终结论:
放到TreeSet或者TreeMap集合kay部分的元素要想做到排序包括两种方式:
第一种:放到集合中的元素实现java.long.Comparable接口
第二种:在构造TreeSet或者TreeMap集合的时候给他传一个比较器对象



这篇关于集合总结的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程