java 集合 Se HashTreeSet
Set是Collection的子接口,与List相对
Set集合中的元素的特点是1,无序性 2,无下标3,无重复的元素
Set是个接口,所以无法直接创建对象,要依赖它的实现类来创建对象
Set的实现类有两个,一个是HashSet,另一个是TreeSet
Set<String> set = new HashSet<>();
set.add("c");
set.add("b");
set.add("d");
set.add("a");
set.add("a");
System.out.println(set);
输出的结果是
[a, b, c, d]//根据输出结果,我们可以看出set 的无序性和无重复性
Set的成员方法基本上都是继承了collection方法
下面我们看一下Set的实现类
HashSet
HashSet是set的实现类,底层是由哈希算法实现的
因为HashSet中能会添加相同的对象,所以HashSet常常被用来去除集合中重复的元素
HashSet<String> hashSet = new HashSet<>();
hashSet.add("a");
hashSet.add("b");
hashSet.add("d");
hashSet.add("d");
System.out.println(hashSet);
输出结果是:
[a, b, d]
根据输出的结果可以看出HashSet确实去除了重复的对象,那么add的底层实现具体是什么?
因为HashSet是由哈希算法来实现的,在一个对象要被添加到集合中的时候,会被系统分配一个哈希值,系统首先会根据这个对象的哈希值去和集合中的对象去比较,如果哈希值不同就可以加入,如果不同,就去比较俩字符串的值是否一样,如果一样就不能加入,因此把重复的对象是无法加入HashSet的
当我们加入的对象是数据类型不是系统的数据类型,我们来看一下HashSet如何去除重复的
先写一个StudentL类,student有俩变量,一个是名字.一个是年龄
public class Student
{
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
下面我们在HashSet集合中添加三个Student类的对象
HashSet<Student> hashSet = new HashSet<>();
hashSet.add(new Student("张三", 18));
hashSet.add(new Student("李四", age));
hashSet.add(new Student("张三", 18));
System.out.println(hashSet);
输出的结果是:
[Student [name=张三, age=18], Student [name=张三, age=18], Student [name=李四, age=19]]
可以看出,俩张三都被添加进去了,但是重复的我们并不想添加进去,为什么会被添加进去呢
这时因为在创建student的时候,我们给每个对象都在堆内存中开辟了一片空间,虽然俩对象中的元素相等,但是他们的地址是不一样的,所以系统认为他们是不同的,所以被添加进去了
如果我们要让系统把student中重复的去掉,我们只能从底层去操作,因为HashSet是系统内部根据比较Hash值来判断的,然后在调用equals方法来比较的,所以我们要重写Object类中的hashCode和equals方法
因为我们要对Student类的对象排序,自然是Student类的对象来调用,所以在Student类中进行方法的重写
//重写hashCode方法
@Override
public int hashCode()
//这里返回的是要添加的对象的哈希值
{
return 1;
}
//重写equals方法
@Override
public boolean equals(Object obj)
{
Student student = (Student)obj;
if (student.name.equals(this.name)&&student.age == this.age)
{
return true;
}
return false;
}
}
我们再次运行,输出的结果是:
[Student [name=张三, age=18], Student [name=李四, age=19]]
这次可以看出重复的对象已经被去除了.
TreeSet
TreeSet是Set的一个实现类,底层是由二叉树实现的
下面我们创建一个TreeSet类型的集合,并将几个整数装进去
TreeSet<Integer> treeSet = new TreeSet<>();
treeSet.add(10);
treeSet.add(8);
treeSet.add(15);
treeSet.add(11);
treeSet.add(8);
System.out.println(treeSet);
输出的结果是
[8, 10, 11, 15]//我们可以根据输出的结果看出TreeSet会将对象排序并将重复的删除了
HashSet的作用就是去除重复的对象,而TreeSet的主要作用就是排序
下面我们在TreeSet中添加非系统类的对象
例:在TreeSet中添加四个学生类对象
TreeSet<Student> treeSet = new TreeSet<>();
treeSet.add(new Student("张三", 18));
treeSet.add(new Student("李四", 19));
treeSet.add(new Student("张三", 18));
System.out.println(treeSet);
当我们运行的时候,会发现系统会报错,这是因为我们添加进去的Student类,不是系统类,系统不知道怎么排序,所以会报错
我们写系统类之所以系统会排序,是因为系统类中都实现了Comparable接口中的比较的抽象方法,系统在add的时候,要添加的系统对象会调用这个比较方法,进行排序和去除重复的对象
所以我们需要在Student类中实现接口,重写接口中的比较方法
//重写comparable接口中的抽象方法,主要是把对象的排序的规则写进去
@Override
//要注意的是当返回值为0的时候,系统就会认为俩值是一样的,就不会添加该对象
public int compareTo(Student o) {
// TODO Auto-generated method stub
int ageNum = this.age - o.age;
int nameNum = this.name.compareTo(o.name);
//当年龄一样的时候,我们就比较俩者的姓名
return ageNum == 0 ? nameNum :ageNum;
}
运行得到的结果是:
[Student [name=张三, age=18], Student [name=李四, age=19]]
可以看出我们的运行结果已经根据年龄排序了,但是这种方法有一个局限,如果该类的对象被装到俩集合中,排序的条件不同,这样的话就没法重写抽象方法了.
这时候我们可以创建每一个集合创建一个比较器,用比较器来排序
我们这里要用到接口Comparator中的比较方法,我们需要给Comparator接口写一个实现类,在类中重写抽象方法 compare(),方法中也是用来写排序的规则的
public class StudentImpl implements Comparator<Student> {
@Override
public int compare(Student o1,Student o2)
{
int intNum = o1.getAge() - o2.getAge();
int nameNum = o1.getName().compareTo(o2.getName());
return nameNum == 0 ? intNum :nameNum;
}
}
在实现了comparator接口后,我们根据其实现类来为TreeSet创建一个比较器
TreeSet<Student> treeSet = new TreeSet<>(new StudentImpl());
treeSet.add(new Student("张三", 18));
treeSet.add(new Student("李四", 19));
treeSet.add(new Student("张三", 18));
System.out.println(treeSet);
这样输出的结果是:
[Student [name=张三, age=18], Student [name=李四, age=19]]
这样即使student类被装到很多个集合中,并且排序的条件不同,我们也可以为每一个集合创建一个特有的比较器来比较
java 集合 Se HashTreeSet的更多相关文章
- 【转】Java集合框架综述
文章目录 1. 集合框架(collections framework) 2. 设计理念 3. 两大基类Collection与Map 3.1. Collection 3.2. Map 4. 集合的实现( ...
- Java集合(1)一 集合框架
目录 Java集合(1)一 集合框架 Java集合(2)一 ArrayList 与 LinkList Java集合(3)一 红黑树.TreeMap与TreeSet(上) java集合(4)一 红黑树. ...
- Java总结——常见Java集合实现细节(1)
Java提高——常见Java集合实现细节(1) 2018年04月18日 15:07:35 阅读数:25 集合关系图 Set和Map set代表一种集合元素无序.集合元素不可重复的集合 map代表一种由 ...
- Java 集合框架(一)—— 接口综述
前言:凡是使用 Java 编程的,几乎肯定会用到集合框架,比如 ArrayList.LinkedList.HashSet.HashMap 等,集合框架的代码绝对是大师级的实现,所以为了更好地使用集合框 ...
- Java集合(一):Java集合概述
注:本文基于JDK 1.7 1 概述 Java提供了一个丰富的集合框架,这个集合框架包括了很多接口.虚拟类和实现类. 这些接口和类提供了丰富的功能.可以满足主要的聚合需求. 下图就是这个框架的总体结构 ...
- Java集合(二):List列表
在上一节中,介绍了Java集合的总体情况.从这节開始,将介绍详细的类.这里不单单介绍类的使用方法.还会试图从源代码的角度分析类的实现.这一节将介绍List接口及实现类.即列表中的链表LinkedLis ...
- JAVA 集合 List 分组的两种方法
CSDN日报20170219--<程序员的沟通之痛> [技术直播]揭开人工智能神秘的面纱 程序员1月书讯 云端应用征文大赛,秀绝招,赢无人机! JAVA 集合 List 分组的两种方法 2 ...
- java集合的简单用法
typora-root-url: iamge [TOC] 1.集合接口 1.1将集合的接口与实现分离 与现代的数据结构类库的常见情况一样,Java集合类库也将接口(interface)与实现(im ...
- 浅谈 Java集合
Java 集合 集合是对象的容器,定义了多个对象进行操作的常用方法,可实现数组的功能. Java集合类库所处位置:java.util.*. 与现代的数据结构类库的常见做法一样,Java集合类库也将接口 ...
随机推荐
- jquery双击事件会触发单击事件
实际工作中,我们经常会遇到在同一个元素上,绑定多种事件类型,比较常见的是单击事件和一些鼠标事件,一般而言影响不大.但是如果同时绑定单击事件和双击事件呢? 其实,只要能够想明白的话,解决方案也比较简单, ...
- 【Fiddler学习】Fiddler抓包HTTPS请求和手机抓包
一.安装Fiddler 百度搜索:Fiddler抓包工具,然后安装即可. 然后打开Fiddler工具,打开浏览器随意输入任何网址,就可以在Fiddler看到抓包信息. 但是:默认情况下,Fiddler ...
- django中路由系统和视图的对应关系(值的传递)-->主要内容(位置参数、关键字参数、额外参数、include分组[urls的分发]、命名分组、反向解析、APPEND_SLASH)
路由系统也就是 urls.py文件,视图就是 views.py文件 路由系统里面要注意的事项 urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续. 若要从UR ...
- UiAutomatorHelper 调试类
package rom; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; impo ...
- uiautomator 代码记录 : 随机发送短信
package sms_test; import java.lang.*; import java.util.Random; import javax.microedition.khronos.egl ...
- tornado-cookies+pycket 验证
1.pip install pycket pip install redis 2.config settings = dict( debug=True, template_path='template ...
- c#生成cad缩略图或者图片
struct BITMAPFILEHEADER{public short bfType;public int bfSize;public short bfReserved1;public short ...
- py库: pyautogui (自动测试模块,模拟鼠标、键盘动作)
PyAutoGUI 是一个人性化的跨平台 GUI 自动测试模块 pyautogui 库 2017-10-4 pip install pyautogui python pip.exe install p ...
- Yii实战中8个必备常用的扩展,模块和widget
Yii实战中8个必备常用的扩展,模块和widget 在经过畅K网 的实战后,总结一下在Yii的项目中会经常用到的组件和一些基本的使用方法,分享给大家,同时也给自己留个备忘录,下面我以代码加图片说明. ...
- oozie 工作流调试及报错
1. oozie 调用sql文件的workflow 错误汇总: 1)hive2server密码错误.(有时设置可以无密码,有时需要登陆密码,有时是单独的hive2server密码) Connecti ...