(Set, Map, Collections工具类)JAVA集合框架二
Java集合框架部分细节总结二
Set
实现类:HashSet,TreeSet
HashSet
基于HashCode计算元素存放位置,当计算得出哈希码相同时,会调用equals判断是否相同,相同则拒绝存入
存储结构:哈希表(数组+链表+红黑树(JDK1.8之后))
即数组上每个元素可追加链表,若HashCode判断相同,而equals判断不同,则会在数组该位置追加Node。超过一定规模,链表转为红黑树存储结构
public static void main(String[] args) {
Set<Student> set = new HashSet<>();
Student s1 = new Student("xiaomign",11);
Student s2 = new Student("xiaohong",12);
Student s3 = new Student("xiaolan",13);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(new Student("xiaolan",13));
System.out.println(set.size());
System.out.println(set);
}
会输出4个Student实例,之所以出现4个,是因为equals判断不相同(是两个地址),重写equals可判断重复
存储过程
- 根据HashCode计算保存位置,若为空,直接包存,否则执行第二步
- 执行equals,若返回true,则认为重复,否则存入(形成链表)
ArrayList实验中曾重写Student,详情可见”ArrayList“
Set<Student> set = new HashSet<>();
Student s1 = new Student("xiaomign",11);
Student s2 = new Student("xiaohong",12);
Student s3 = new Student("xiaolan",13);
set.add(s1);
set.add(s2);
set.add(s3);
set.add(new Student("xiaolan", 13));
若不改动重写代码,则该段执行,出现4个元素,原因在于第一步判断不为空
想让第一步判断为空,需要重写hashCode(),例:
@Override
public int hashCode() {
int n1 = this.name.hashCode();
int n2 = age;
return n1+n2;
}
重写一二步判断后,则集合中为3个元素
alt+insert可直接调用工具,以下为IDEA自动重写代码
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return getAge() == student.getAge() &&
Objects.equals(getName(), student.getName());
}
@Override
public int hashCode() {
return Objects.hash(getName(), getAge());
}
遍历:增强for,迭代器
PS:
有些版本的重写hashCode()
执行原理是,定义一个Int(31),质数减少散列冲突;提高执行效率:31*i == (i<<5)-i 取31,内部可以进行移位操作
TreeSet
基于排列顺序实现元素不重复
实现SortedSet接口,对集合元素自动排序
元素对象的类型必须实现Comparable接口,指定排序规则,通过CompareTo方法确定是否为重复元素
TreeSet的存储结构为红黑树,红黑树结构即为二叉查找树,数据结构与算法后续将介绍
TreeSet<Student> treeSet = new TreeSet<>();
Student s1 = new Student("xiaomign",11);
Student s2 = new Student("xiaohong",12);
Student s3 = new Student("xiaolan",13);
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
举例一段代码,该段代码不能执行
Student cannot be cast to class java.lang.Comparable
使用TreeSet必须要求元素能够实现Comparable接口,Student类实现Comparable接口里重写CompareTo()
@Override
public int compareTo(Student o) {
int n1 = getName().compareTo(o.getName());
int n2 = getAge()-o.getAge();
return n1==0?n2:n1;
}
该重写的比较规则,先比姓名再比年龄,重写后已能删除,总结:只要实现了比较方式,无论重写哈希还是compareTo都可实现删除等操作。
Comparator接口:实现定制比较(比较器)
实现:
TreeSet<Person> people = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1 = o1.getName().compareTo(o2.getName());
int n2 = o1.getAge()-o2.getAge();
return n1==0?n2:n1;
}
});
在实例化过程中直接定义比较器,不需要在Person类中实现Comparable
Map
实现类:HashMap,TreeMap,Hashtable(JDK1.0,目前基本不用了)
特点:存储任意键值对(Key-Value),类似python字典
- Key:无序,无下标,不允许重复(key的判定实际上还是equals和hashCode)
- Value:无序,无下标,允许重复
HashMap
JDK1.2,线程不安全,运行效率快,允许用null作为K或V,构造一个具有默认初始容量16(int)和默认加载因子0.75(float)的空HashMap
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
static final float DEFAULT_LOAD_FACTOR = 0.75f;
HashMap<String,Integer> hashMap = new HashMap<>();
刚创建的时候hashMap=null, size=0;添加第一个元素之后,才赋值默认初始容量;节省空间
当Size超过加载因子规定的容量,第一轮为Size>12时,容量扩展为2倍,newCap为oldCap向左移位了一位
JDK1.8,当链表长度大于8,且Size大于等于64时,链表调整为红黑树,目的是提高执行效率。当链表长度小于6时,调整为链表结构。JDK1.8以前链表是头插入,1.8及以后是尾插入
存储结构:哈希表
遍历方式 entrySet() 返回值类型<K,V>
//增强for
for(Object ob:hashMap.keySet()){
System.out.println(ob+hashMap.get(ob).toString());
}
for(Map.Entry<String,Integer> entry :hashMap.entrySet()) {
System.out.println(entry);
}
同一Key的map中,add之后会覆盖前一个的Value
Hashtable:线程安全,运行效率慢,不允许null作为K或V(初始容量11,加载因子0.75)
Properties:Hashtable的子类,要求K和V均为String,经常用于配置文件的读取(后续会写,涉及流的概念)
Treemap
实现了SortedMap接口(Map子接口),可以对key自动排序
排序过程和TreeSet类似,要满足Comparable接口,两种重写比较方法
遍历方法同HashMap
Collections工具类
常用的有
public static void reverse(List<?>list); //反转集合中元素顺序
public static void shuffle(List<?>list); //随机重置集合中元素顺序
public static void sort(List<T>list); //升序排列(元素类型必须实现Comparable接口)
举例:
Collections.sort(list);
System.out.println(list);
int i =Collections.binarySearch(list,20);
System.out.println(i);//负数则为未找到
注意:
Collections.copy(list1,list);
System.out.println(list1);
copy方法要求两个List大小相同,若list1为刚实例化,则size为0;而list若有元素,size必不为0;无法完成copy
for(int j=0 ; j < list.size() ; j++)
list1.add(0);
解决方法如上,本demo中list1和list均为Integer类型
Integer[]n = list.toArray(new Integer[0]);
for(Object ob:n){
System.out.println(ob);
}
.toArray方法,参数为 T[ ],上述代码若new Integer的大小大于list的大小,则空白处为null,因为Integer为引用类型,默认为null
String[] name = {"apple","pear","banana"};
List<String> list2 = Arrays.asList(name);
System.out.println(list2);
上述为Arrays工具类,与toArray类似,该例中list2不能改动,是一个受限集合
Integer[] num = {1,2,3,4};
List<Integer> list3 = Arrays.asList(num);
System.out.println(list3);
整数数组转List建议这样写,因为int[]之后,下方的泛型也需要使用 int[],这样的话,list中存储的每个元素都是一个数组
基本总结就是这样了,在将来上述有些知识会陆续补充或放在新的博客里,本博客只显示了集合框架中的大概。
(Set, Map, Collections工具类)JAVA集合框架二的更多相关文章
- [19/03/27-星期三] 容器_Iterator(迭代器)之遍历容器元素(List/Set/Map)&Collections工具类
一.概念 迭代器为我们提供了统一的遍历容器的方式 /* *迭代器遍历 * */ package cn.sxt.collection; import java.security.KeyStore.Ent ...
- java 集合框架(二)Iterable接口
Iterable接口是java 集合框架的顶级接口,实现此接口使集合对象可以通过迭代器遍历自身元素,我们可以看下它的成员方法 修饰符和返回值 方法名 描述 Iterator<T> iter ...
- Java集合框架(二)
Set Set:无序,不可以重复元素. |--------HashSet:数据结构是哈希表. 线程是非同步的.保证元素唯一性的原理是:判断元素的hashCode值是否相同,如果相同,还会继续判断元素的 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_07 Collections工具类_1_Collections集合工具类的方法
这是一个个的添加的方式 参数是个可变的元素.可以传递任意多的元素 shuffle打乱集合元素顺序
- 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_07 Collections工具类_2_Collections集合工具类的方法
默认规则一般都是升序排序 再来创建一个字符串的数组 排序后,按照升序输出结果 自定义类型排序 创建一个Person类,getter和setter 有参构造和无参构造 重写toString的方法 传对象 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_07 Collections工具类_3_Collections集合工具类的方法
第二个参数传递了一个匿名内部类.结果就出现了下面的代码 源码里面有Compare方法,对比两个参数 要重写比较的方法 对对象进行排序 创建学生类.对学生类进行排序 重写Person的ToString方 ...
- 【集合系列】- 初探java集合框架图
一.集合类简介 Java集合就像一种容器,可以把多个对象(实际上是对象的引用,但习惯上都称对象)"丢进"该容器中.从Java 5 增加了泛型以后,Java集合可以记住容器中对象的数 ...
- java 集合Collections 工具类:排序,查找替换。Set、List、Map 的of方法创建不可变集合
Collections 工具类 Java 提供1个操作 Set List Map 等集合的工具类 Collections ,该工具类里提供了大量方法对集合元素进行排序.查询和修改等操作,还提供了将集合 ...
- java集合框架复习----(4)Map、List、set
文章目录 五.Map集合[重要] 1.hashMap 六.Collections工具类 总结 集合的概念 List集合 set集合: Map集合 Collection 五.Map集合[重要] 特点: ...
随机推荐
- NGK公链助力医疗行业数据安全
近年来医疗领域的数据泄露事件时有发生,医疗行业数据面临着医疗数据获得不易及缺乏有效管理和数据安全机制问题.而区块链的去中心化.分布式账本等特点正好契合医疗领域的需求点. 医疗数据市场痛点 一.医疗信息 ...
- 如何成为NGK超级节点?
NGK这个 "超级节点" 到底是什么?什么是超级节点呢? 区块链网络中的每一个节点,其实就是存储数据的每一台电脑或者服务器终端.节点要完成新区块的生产.交易的验证与记帐.因此节点之 ...
- (1)MySQL进阶篇在linux环境下安装
1.概述 对于mysql二进制安装,优点是可以安装到任何路径下,灵活性好,一台服务器可以安装多个mysql.缺点是已经编译过,性能不如源码编译得好,不能灵活定制编译参数.如果用户即不想安装最简单却不够 ...
- 利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解
本文转载自利用 Java 操作 Jenkins API 实现对 Jenkins 的控制详解 导语 由于最近工作需要利用 Jenkins 远程 API 操作 Jenkins 来完成一些列操作,就抽空研究 ...
- 微信小程序(一)-工具创建和结构配置说明 Stable Build
按装前特别说明: windows最好下载32位的,不然用到用到后面就出现"网络连接失败",然后就登录不上去了,打不开编辑器了! 问题 : 微信开发者工具网络连接失败, " ...
- 死磕Spring之IoC篇 - 解析自定义标签(XML 文件)
该系列文章是本人在学习 Spring 的过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring 源码分析 GitHub 地址 进行阅读 Spring 版本:5.1. ...
- lombok插件@Slf4j注解不生效问题解决办法
最近在尝试使用日志工具Sfl4j,当时使用log时报错,找了好久才解决这个问题. 1.首先需要下载Lombok插件 File->settings->Plugins 搜索Lombok,点击安 ...
- 【转载】UML类图中箭头和线条的含义和用法
文章转载自 http://blog.csdn.net/hewei0241/article/details/7674450 https://blog.csdn.net/iamherego/article ...
- ant-design-vue中table自定义列
1. 使用背景 在项目中使用ant-vue的a-table控件过程中,需要显示序号列或者在列中显示图片,超链,按钮等UI信息.经过查询文档customCell和customRender可以实现以上需求 ...
- 2020年12月-第02阶段-前端基础-CSS Day07
CSS Day07 CSS高级技巧 理解 能说出元素显示隐藏最常见的写法 能说出精灵图产生的目的 能说出去除图片底侧空白缝隙的方法 应用 能写出最常见的鼠标样式 能使用精灵图技术 能用滑动门做导航栏案 ...