排序及重复元素去重的说明,TreeSet,HashSet
先看下面一段代码:
package 类集;
import java.util.Set;
import java.util.TreeSet;
class Person{
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
public String gtoString(){
return "姓名:" + this.name + ";年龄:" + this.age ;
}
}; public class test1{
public static void main(String args[]){
Set<Person> allSet = new TreeSet<Person>() ;
allSet.add(new Person("张三",30)) ;
allSet.add(new Person("李四",31)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("赵六",33)) ;
allSet.add(new Person("孙七",33)) ;
System.out.println(allSet) ;
}
};
运行结果:
Exception in thread "main" java.lang.ClassCastException: 类集.Person 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 类集.test1.main(test1.java:19)
报错。此时没有排序,因为java.lang.comparable类导致。
comparable是进行排序的接口。一个对象数组要想排序需要依靠comparable接口完成。对于treeset一样,要想进行排序,则对象所在的类也要依靠comparable接口。
修改如下,要想排序,对象所在的类也要依靠comparable接口(继承之)。
package 类集;
import java.util.Set;
import java.util.TreeSet;
class Person implements Comparable<Person>{
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
public String toString(){
return "姓名:" + this.name + ";年龄:" + this.age ;
}
public int compareTo(Person per){ //这里需要复习comparable接口的知识
if(this.age>per.age){
return 1 ;
}else if(this.age<per.age){
return -1 ;
}else{
return 0 ;
}
}
};
public class test1{
public static void main(String args[]){
Set<Person> allSet = new TreeSet<Person>() ;
allSet.add(new Person("张三",30)) ;
allSet.add(new Person("李四",31)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("赵六",33)) ;
allSet.add(new Person("孙七",33)) ;
System.out.println(allSet) ;
}
};
输出结果:
[姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:赵六;年龄:33]
string类既然可以使用TreeSet排序,则String中肯定已经实现了Comparable接口。
string类定义如下:
public final class Stringextends Objectimplements Serializable, Comparable<String>, CharSequence
此时是可以排序了,但是结果有问题,
[姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:赵六;年龄:33]
发现去掉了重复的元素(王五),依靠的是comparable接口完成的。孙七没有加入进来,因为孙七和赵6年龄是完全一样的,而此时的comparable接口比较的只是年龄。
为了保证正确,所有的属性都应该进行比较:改成如下:
package 类集;
import java.util.Set;
import java.util.TreeSet;
class Person implements Comparable<Person>{
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
public String toString(){
return "姓名:" + this.name + ";年龄:" + this.age ;
}
public int compareTo(Person per){
if(this.age>per.age){
return 1 ;
}else if(this.age<per.age){
return -1 ;
}else{
return this.name.compareTo(per.name) ; // 调用String中的compareTo()方法
}
}
};
public class test1{
public static void main(String args[]){
Set<Person> allSet = new TreeSet<Person>() ;
allSet.add(new Person("张三",30)) ;
allSet.add(new Person("李四",31)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("赵六",33)) ;
allSet.add(new Person("孙七",33)) ;
System.out.println(allSet) ;
}
};
输出结果:
[姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:孙七;年龄:33, 姓名:赵六;年龄:33]
此时的去重元素并不是真正意义上的重复元素取消。
用hashSet试试,hashset不排序。
package 类集;
import java.util.HashSet;
import java.util.Set;
class Person{
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
public String toString(){
return "姓名:" + this.name + ";年龄:" + this.age ;
}
};
public class test1{
public static void main(String args[]){
Set<Person> allSet = new HashSet<Person>() ;
allSet.add(new Person("张三",30)) ;
allSet.add(new Person("李四",31)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("赵六",33)) ;
allSet.add(new Person("孙七",33)) ;
System.out.println(allSet) ;
}
};
输出结果:
[姓名:王五;年龄:32, 姓名:赵六;年龄:33, 姓名:孙七;年龄:33, 姓名:王五;年龄:32, 姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32]
此时并没有去掉重复的元素,该如何取消呢,
如果要想去掉重复,则需要object类中两个方法帮助。
1,hashcode():表示一个唯一编码,一般通过计算表示。
2)equals():进行对象的比较操作。
我们需要覆写这两个方法!
package 类集;
import java.util.HashSet;
import java.util.Set;
class Person{
private String name ;
private int age ;
public Person(String name,int age){
this.name = name ;
this.age = age ;
}
public boolean equals(Object obj){ // 覆写equals,完成对象比较
if(this==obj){
return true ;
}
if(!(obj instanceof Person)){
return false ;
}
Person p = (Person)obj ; // 向下转型
if(this.name.equals(p.name)&&this.age==p.age){
return true ;
}else{
return false ;
}
}
public int hashCode(){
return this.name.hashCode() * this.age ; // 自己定义一个公式,如上所写。
}
public String toString(){
return "姓名:" + this.name + ";年龄:" + this.age ;
}
};
public class test1{
public static void main(String args[]){
Set<Person> allSet = new HashSet<Person>() ;
allSet.add(new Person("张三",30)) ;
allSet.add(new Person("李四",31)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("王五",32)) ;
allSet.add(new Person("赵六",33)) ;
allSet.add(new Person("孙七",33)) ;
System.out.println(allSet) ;
}
};
输出结果:
[姓名:赵六;年龄:33, 姓名:王五;年龄:32, 姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:孙七;年龄:33]
此时没有了重复元素。
如果要想使用Set,必须注意以上两个问题,
1,一个好的类应该覆写object类中的equals(),hashCode(),toString()三个方法,实际上在String()中已经覆写完成了。
2,Set接口依靠hashCode()和equals()完成重复元素的判断,关于这一点,在以后的Map接口中也有体现。
3,TreeSet依靠Comparable完成排序的操作。
排序及重复元素去重的说明,TreeSet,HashSet的更多相关文章
- 吴裕雄--天生自然java开发常用类库学习笔记:排序及重复元素说明
import java.util.Set ; import java.util.HashSet ; class Person{ private String name ; private int ag ...
- Java思考——HashSet集合如何保证元素的唯一性也就是不包含重复元素?
首先将源码逐级找出来1.HashSet<String> hs=new HashSet<String>(); hs.add("hello"); ...
- iOS数组的去重,判空,删除元素,删除重复元素 model排序 等
一: 去重 有时需要将NSArray中去除重复的元素,而存在NSArray中的元素不一定都是NSString类型.今天想了想,加上朋友的帮助,想到两种解决办法,先分述如下. 1.利用NSDiction ...
- java8 stream初试,map排序,list去重,统计重复元素个数,获取map的key集合和value集合
//定义一个100元素的集合,包含A-Z List<String> list = new LinkedList<>(); for (int i =0;i<100;i++) ...
- TreeSet和TreeMap不能存放重复元素?能不能存放null?
问题一:本来认为TreeMap不能存放重复元素?其实并非如此: 其实一般情况下是不允许存放重复元素的,但是它并非这么死板,在一些情况下是可以存放重复元素的,存了又会有引入其他问题. 问题二:能不能存放 ...
- TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树
TreeSet和TreeMap不能存放重复元素?能不能存放null?其实不是这样的——灵活的二叉树 本文链接:https://blog.csdn.net/u010698072/article/de ...
- java: Set类及子类:TreeSet有序子类,HashSet无序子类:重复元素
Set类及子类: TreeSet有序子类: HashSet无序(散列)子类 HashSet子类的内容是没有顺序的,单个元素也不会重复的(对象除外). Set<String> allSet ...
- lintcode :Remove Duplicates from Sorted List 删除排序链表中的重复元素
题目: 删除排序链表中的重复元素 给定一个排序链表,删除所有重复的元素每个元素只留下一个. 您在真实的面试中是否遇到过这个题? 样例 给出1->1->2->null,返回 1-& ...
- leetcode-83.删除排序链表中的重复元素
leetcode-83.删除排序链表中的重复元素 Points 链表 题意 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2 输出: 1- ...
随机推荐
- 之二:CAKeyframeAnimation - 关键帧动画
是CApropertyAnimation的子类,跟CABasicAnimation的区别是:CABasicAnimation只能从一个数值(fromValue)变到另一个数值(toValue),而CA ...
- .Net控件经验集合
一.DropDownList默认选中 开始的笨方法: foreach (ListItem item in DropDownList1.Items) { ...
- Java中"\t"表示几个空格
\t是补全当前字符串长度到8的整数倍,最少1个最多8个空格补多少要看你\t前字符串长度 测试程序: 测试结果: 总结:运行到“\t”时,判断当前字符串长度,将当前字符串长度补到8的倍数(不包括0).
- 软件光栅化渲染器Augustus计划
在看完Real-Time Rendering后,我决定动手实现一个软件的光栅化渲染器.我就称它为Augustus计划吧. 计划使用MFC和GDI+来做它的UI.可以访问GitHub来查看它的源代码.
- Java中怎样创建线程安全的方法
面试问题: 下面的方法是否线程安全?怎样让它成为线程安全的方法? class MyCounter { private static int counter = 0; public static int ...
- JavaWeb 的学习一
JavaWeb学习总结(一)——JavaWeb开发入门 一.基本概念 1.1.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Inte ...
- spring listener监听器
1.Listener的定义与作用 监听器Listener就是在application,session,request三个对象创建.销毁或者往其中添加修改删除属性时自动执行代码的功能组件. Listen ...
- javax.servlet.ServletException cannot be resolved to a type错误解决方法
在页面中使用全局路径时${pageContext.request.contextPath}出现javax.servlet.ServletException cannot be resolved to ...
- 企业邮箱在Android(安卓)系统手机上POP3/IMAP协议的设置方法
此处以三星(系统版本4.4.2)为例,介绍下使用安卓系统自带的客户端如何设置pop/imap协议方式方法 以下我们将使用test@zhuyuming.so 为测试案例,请您操作时更换成您自己的邮箱账号 ...
- Linux基本操作命令之文件查看cat more less tail head
cat 参考之前博客:Linux基础命令之cat使用方法大全 more 命令 命令:more使用权限:所有使用者使用方式:more [选项] filename说明:类似于cat,不过会一页一页的显示内 ...