关于List、Set、Map接口讲解
概述
List、Set接口都是继承于Collection主接口,而Map为独立接口
1、List接口下有ArrayList、Vector、LinkedList实现类
2、Set接口下有HashSet、LinkedHashSet、TreeSet实现类
3、Map下有HashMap、LinkedHashMap、Hashtable、TreeMap实现类
特点
Collection接口:
——List接口 有序,可重复
ArrayList
优点: 底层数据结构是数组,查询快,增删慢
缺点: 线程不安全,效率高
LinkedList
优点: 底层数据结构是链表,查询慢,增删快
缺点: 线程不安全,效率高
Vector
优点: 底层数据结构是数组,查询快,增删慢
缺点: 线程安全,效率低
——Set 无序,唯一
HashSet
底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
答:依赖两个方法:hashCode()和equals()
LinkedHashSet
底层数据结构是链表和哈希表 (FIFO插入有序,且唯一)
原因如下两点:
答:1.由链表保证元素有序
2.由哈希表保证元素唯一
TreeSet
底层数据结构是红黑树。(唯一,且有序)
1. 如何保证元素排序的呢?
答:1.自然排序
2.比较器排序
2.如何保证元素唯一性的呢?
答:根据比较的返回值是否是0来决定
针对于Collection集合我们到底如何使用呢?(重点掌握)
唯一吗?
是:Set
排序吗?
是:TreeSet或LinkedHashSet
否:HashSet
如果你知道是Set,但是不知道是哪个Set,就用HashSet。
--------------------------------------------------------------------------------------
否:List
要安全吗?
是:Vector
否:ArrayList或者LinkedList
查询多:ArrayList
增删多:LinkedList
如果你知道是List,但是不知道是哪个List,就用ArrayList。如果你知道是Collection集合,但是不知道使用谁,就用ArrayList。
Map接口:
Map接口有三个重要的实现类,分别是 HashMap、LinkedHashMap、Hashtable
1、TreeMap是有序的,HashMap和Hashtable是无序的。
2、Hashtable的方法是同步的,底层源码方法有(synchronized)这是两者主要区别。
这就意味着:
3、Hashtable是线程安全,HashMap是非线程安全。
4、HashMap效率较高,Hashtable效率较低.
重点问题重点分析
(一)、TreeSet,LinkedHashSet and HashSet 的区别
1.介绍
TreeSet,LinkedHashSet and HashSet 在Java中都是实现Set的数据结构
1.TreeSet的主要功能用于排序
2.LinkedHashSet的主要功能用于保证FIFO即有序的集合(先进先出)
3.HashSet只是通用的存储数据的集合
2.相同点
重复元素:因为三者都实现Set interface,所以三者都不包含重复元素.
线程安全:三者都不是线程安全的,如果要使用线程安全可以Collections.synchronizedSet()
3.不同点
性能和速度:HashSet插入数据最快,其次LinkHashSet,最慢的是TreeSet因为内部实现排序。
排序:HashSet不保证有序,LinkHashSet保证FIFO即按插入顺序排序,TreeSet安装内部实现排序,也可以自定义排序规则。
Null:HashSet和LinkHashSet允许存在null数据,但是TreeSet中插入null数据时会报NullPointerException异常。
4.不多说了上代码进行比较!
package com.jia.set; import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet; public class SetDemo { public static void main(String args[]) { HashSet<String> hashSet = new HashSet<>();
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
TreeSet<String> treeSet = new TreeSet<>(); for (String data : Arrays.asList("B", "A", "D", "C", "E")) {
hashSet.add(data);
linkedHashSet.add(data);
treeSet.add(data);
} // 不保证有序
System.out.println("HashSet排序 :" + hashSet); // FIFO保证安装插入顺序排序
System.out.println("LinkedHashSet插入顺序排序 :" + linkedHashSet); // 内部实现排序
System.out.println("TreeSet内部排序 :" + treeSet); } }
运行结果:
HashSet排序 :[A, B, C, D, E]
LinkedHashSet插入顺序排序 :[B, A, D, C, E]
TreeSet内部排序 :[A, B, C, D, E]
(二)、TreeSet的两种排序方式比较
1.排序的引入 (以基本数据类型的排序为例)
package com.jia.set; import java.util.TreeSet; public class TreeSetDemo { public static void main(String[] args) { // 创建集合对象
// 自然顺序进行排序
TreeSet<Integer> treeSet = new TreeSet<Integer>(); // 创建元素并添加
// 3,6,9,12,15,18,21,22,30
treeSet.add(3);
treeSet.add(6);
treeSet.add(9);
treeSet.add(12);
treeSet.add(15);
treeSet.add(18);
treeSet.add(21);
treeSet.add(22);
treeSet.add(30); // 遍历结果
for (Integer data : treeSet) {
System.out.println("TreeSet --> "+data);
}
}
}
运行结果:
TreeSet --> 3
TreeSet --> 6
TreeSet --> 9
TreeSet --> 12
TreeSet --> 15
TreeSet --> 18
TreeSet --> 21
TreeSet --> 22
TreeSet --> 30
2.如果是引用数据类型来说,比如自定义对象,又该如何排序呢?
比如创建一个学生类:
package com.jia.set; //学生类
public class Student { private Integer id;
private String name; public Student() {
} public Student(Integer id, String name) {
this.id = id;
this.name = name;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
测试类:
package com.jia.set; import java.util.TreeSet; public class StudentTreeSetDemo { public static void main(String[] args) { TreeSet<Student> treeSet = new TreeSet<Student>();
//创建元素对象
Student s1=new Student(1,"张三");
Student s2=new Student(2,"李四");
Student s3=new Student(3,"王五");
Student s4=new Student(4,"赵六");
Student s5=new Student(5,"陈七");
Student s6=new Student(6,"杨八"); //将元素对象添加到集合对象中
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
treeSet.add(s4);
treeSet.add(s5);
treeSet.add(s6); //遍历结果
for (Student student : treeSet) {
System.out.println(student.getId()+"--->"+student.getName());
}
}
}
结果报错:
Exception in thread "main" java.lang.ClassCastException: com.jia.set.Student cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1294)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at com.jia.set.StudentTreeSetDemo.main(StudentTreeSetDemo.java:20)
原因分析:
由于不知道该安照那一中排序方式排序,所以会报错。
解决方法:
1.自然排序
2.比较器排序
(1)自然排序
自然排序要进行一下操作:
1.Student类中实现Comparable接口
2.重写Comparable接口中的Comparable()方法
public int compareTo(T o); 比较此对象与指定对象的顺序。
package com.jia.set; //学生类
public class Student implements Comparable<Student> { private Integer id;
private String name; public Student() {
} public Student(Integer id, String name) {
this.id = id;
this.name = name;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
'}';
} @Override
public int compareTo(Student s) {
//return -1; //-1表示放在红黑树的左边,即逆序输出
//return 1; //1表示放在红黑树的右边,即顺序输出
//return o; //表示元素相同,仅存放第一个元素
//主要条件 姓名的长度,如果姓名长度小的就放在左子树,否则放在右子树
int num = this.name.length()-s.name.length();
//姓名的长度相同,不代表内容相同,如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。
//如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。
//如果这两个字符串相等,则结果为 0
int num1 = num==0?this.name.compareTo(s.name):num;
//姓名的长度和内容相同,不代表id值相同,所以还要判断id
int num2=num1==0?this.id-s.id:num1;
return num2;
}
}
运行结果:
1--->张三
2--->李四
6--->杨八
3--->王五
4--->赵六
5--->陈七
(2)比较器排序
步骤:1.单独创建一个比较类,以ComparatorTest为例,并且让其继承Comparator接口
2.重写Comparable接口中的Comparable()方法
compare(T o1,T o2) 比较用来排序的两个参数。
TreeSet(Comparator<? superE> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。
创建比较类ComparatorTest:
package com.jia.set; import java.util.Comparator; public class ComparatorTest implements Comparator<Student> { @Override
public int compare(Student s1,Student s2) {
// 姓名长度
int num = s1.getName().length() - s2.getName().length();
// 姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
// id值
int num3 = num2 == 0 ? s1.getId() - s2.getId() : num2; return num3;
}
}
学生类:
package com.jia.set; //学生类
public class Student { private Integer id;
private String name; public Student() {
super();
} public Student(Integer id, String name) {
this.id = id;
this.name = name;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} }
测试类:
package com.jia.set; import java.util.TreeSet; public class StudentTreeSetDemo { public static void main(String[] args) { TreeSet<Student> treeSet = new TreeSet<Student>(new ComparatorTest());
//创建元素对象
Student s1=new Student(1,"张三");
Student s2=new Student(2,"李四");
Student s3=new Student(3,"王五");
Student s4=new Student(4,"赵六");
Student s5=new Student(5,"陈七");
Student s6=new Student(6,"杨八"); //将元素对象添加到集合对象中
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
treeSet.add(s4);
treeSet.add(s5);
treeSet.add(s6); //遍历结果
for (Student student : treeSet) {
System.out.println(student.getId()+"--->"+student.getName());
}
}
}
运行结果:
1--->张三
2--->李四
6--->杨八
3--->王五
4--->赵六
5--->陈七
性能就不多讲了:HashSet > LinkedHashSet > TreeSet
关于List、Set、Map接口讲解的更多相关文章
- JavaSet接口、唯一元素和Map接口整理
Set接口 1.1 HashSet集合存储数据的结构(哈希表) HashSet集合,采用哈希表结构存储数据,保证元素唯一性的方式依赖于:hashCode()与equals()方法. 哈希表底层,使用的 ...
- Java集合框架——Map接口
第三阶段 JAVA常见对象的学习 集合框架--Map集合 在实际需求中,我们常常会遇到这样的问题,在诸多的数据中,通过其编号来寻找某一些信息,从而进行查看或者修改,例如通过学号查询学生信息.今天我们所 ...
- java中集合类中Collection接口中的Map接口的常用方法熟悉
1:Map接口提供了将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值.Map接口中同样提供了集合的常用方法. 2:由于Map集合中的元素是通过key,value,进行存储的,要 ...
- 第19章 集合框架(3)-Map接口
第19章 集合框架(3)-Map接口 1.Map接口概述 Map是一种映射关系,那么什么是映射关系呢? 映射的数学解释 设A,B是两个非空集合,如果存在一个法则,使得对A中的每一个元素a,按法则f,在 ...
- Map接口使用注意事项
1,Map接口对象本身不能直接使用迭代进行输出的.因为map每个位置存放的是一对值. 而iterator每次只能找到一个值.如果一定要迭代输出,可以通过以下步骤.: 但是,Map接口只作为查找使用,输 ...
- Map接口,Map.Entry,hashMap类,TreeMap类,WeakHashMap。
Collection接口之前接触过,每次保存的对象是一个对象,但是在map中保存的是一对对象,是以key->value形式保存的. 定义: public interface Map<K,V ...
- List接口、Set接口、Map接口的方法
一.Collection接口中的方法介绍 int size();返回此Collection中的元素数 boolean isEmpty(); 判断是否为空 boolean containsAll(Col ...
- Java集合中Map接口的使用方法
Map接口 Map提供了一种映射关系,其中的元素是以键值对(key-value)的形式存储的,能够实现根据key快速查找value: Map中的键值对以Entry类型的对象实例形式存在: 建(key值 ...
- JAVA ,Map接口 ,迭代器Iterator
1. Map 接口概述 java.util.Map 接口描述了映射结构, Map 接口允许以键集.值集合或键 - 值映射关系集的形式查看某个映射的内容. Java 自带了各种 Map 类. 这些 ...
随机推荐
- Solution Set -「LOCAL」冲刺省选 Round XXI
\(\mathscr{Summary}\) 省选几个小时啊,怎么模拟赛只打三个小时啊./kk 时间安排较为合理,没有出现严重的因思考时间过少引起的丢分. A 题比较可惜,二分 + 点分治大 ...
- 私有化轻量级持续集成部署方案--04-私有代码仓库服务-Gitea
提示:本系列笔记全部存在于 Github, 可以直接在 Github 查看全部笔记 企业级最流行的私有代码仓库是 Gitlab, 一开始我也打算部署 Gitlab作为私有代码仓库. 但部署完 d 成后 ...
- 阿里云人脸1:N搜索开源版-Java版(文末附开源地址)
一.人脸检测相关概念 人脸检测(Face Detection)是检测出图像中人脸所在位置的一项技术,是人脸智能分析应用的核心组成部分,也是最基础的部分.人脸检测方法现在多种多样,常用的技术或工具大 ...
- (翻译) CAP 理论 FAQ
CAP 理论 FAQ 0. 关于这个文档 没有其它比CAP理论更引人注意的话题了, 这个FAQ的目的, 是说明对于CAP, 当前哪些是已知的, 并帮助那些刚接触这个理论的人快速了解, 并解决一些错误的 ...
- 关于Linux操作系统的命令行文件拷贝
关于Linux操作系统的命令行文件拷贝 起因:服务器的加密狗秘钥过期导致无法使用服务,需要将服务器里面的秘钥文件发送给授权人员.本以为十分容易,打开服务器,图形界面点击发送即可.没想到服务器的界面是命 ...
- Python 面向对象编程之封装的艺术
1. 面向对象编程 OOP ( Object Oriented Programming) 即面向对象编程. 面向对象编程是一种编码思想,或是一种代码组织方式.如同编辑文章时,可以选择分段.分节的方式 ...
- 华为eNSP环境,WLAN简介与组网,AP+AC详细配置
WLAN简单组网一.概述 无线局域网(Wireless Local Area Networks: WLAN)利用无线技术在空中传输数据.话音和视频信号.作为传统布线网络的一种替代方案或延伸,无线 ...
- 5大知名的BI工具对比介绍
工欲善其事,必先利其器.企业对于BI工具的需求,已经刻不容缓.国内国外的BI工具不少,如Tableau.FineBI.Power BI.Smartbi等等.本文就对当下市面上最热门的5款知名的BI工具 ...
- C#依赖注入-初步概念了解
维基百科说:"依赖注入是一种软件设计模式,在这种模式下,一个或更多的依赖(或服务)被注入(或者通过引用传递)到一个独立的对象(或客户端)中,然后成为了该客户端状态的一部分.该模式分离了客户端 ...
- .NET组件 vs. COM组件
本文转载:https://www.cnblogs.com/larissa-0464/p/11095203.html 写在前面:我没有开发过COM组件的经验,只是在做文献综述的时候需要了解这方面的知识, ...