博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
排序及重复元素去重的说明,TreeSet,HashSet
阅读量:7237 次
发布时间:2019-06-29

本文共 5982 字,大约阅读时间需要 19 分钟。

先看下面一段代码:

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
allSet = new TreeSet
() ; 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
{ 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
allSet = new TreeSet
() ; 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
, CharSequence

此时是可以排序了,但是结果有问题,

[姓名:张三;年龄:30, 姓名:李四;年龄:31, 姓名:王五;年龄:32, 姓名:赵六;年龄:33]

发现去掉了重复的元素(王五),依靠的是comparable接口完成的。孙七没有加入进来,因为孙七和赵6年龄是完全一样的,而此时的comparable接口比较的只是年龄。

为了保证正确,所有的属性都应该进行比较:改成如下:

package 类集;import java.util.Set;import java.util.TreeSet;class Person implements Comparable
{ 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
allSet = new TreeSet
() ; 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
allSet = new HashSet
() ; 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
allSet = new HashSet
() ; 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完成排序的操作

转载地址:http://bmrfm.baihongyu.com/

你可能感兴趣的文章
python对redis的常用操作 上 (对列表、字符串、散列结构操作)
查看>>
I.MX6 i2c_data_write_byte ioctl error: I/O error
查看>>
myisam MySQL 锁问题
查看>>
为什么获取的System.Web.HttpContext.Current值为null,HttpContext对象为null时如何获取程序(站点)的根目录...
查看>>
告诉你一个真实的OpenStack:都谁在用,用来干什么?
查看>>
在idea中maven项目jdk编译version总是跳到1.5
查看>>
理解与应用css中的display属性
查看>>
升级openssl环境至openssl-1.1.0c
查看>>
javaScript判断浏览器类型
查看>>
SQL注入之SQLmap入门
查看>>
Hibernate缓存研究
查看>>
Cesium原理篇:3D Tiles(1)渲染调度
查看>>
neuroph Perceptron Sample
查看>>
关于navicat连接oracle 报 ORA-12737 set CHS16GBK错误的解决方案
查看>>
MEP自定义参数化风机盘管族
查看>>
(android控件)巧用background属性,实现图片可选择效果
查看>>
获取APK文件的签名信息,反射实现
查看>>
Hive On Spark hiveserver2方式使用
查看>>
如何在Android开发中让你的代码更有效率
查看>>
Visual Studio项目的生成事件代码
查看>>