JAVA集合框架之List HashSet去重及TreeSet排序详解

无图言屌!先上图
我们先看看集合间的关系

说到List去重,很多人都知道用contains()方法,其实contains()方法依据的equals()方法,比较两个对象的引用是否相同,如果要List比较两个自定义定义对象是否相同要重写equals方法。贴出代码吧!
`import java.util.*;
class Student
{
private String name;
private int age;

Student(){}
Student(String name,int age)
{
    this.name = name;
    this.age = age;
}

public boolean equals(Object obj)
{
    if(!(obj instanceof Student))
        throw new RuntimeException("类型不对");
    Student stu = (Student)obj;
    System.out.println(this.name+"比较..."+stu.name);
    return this.name.equals(stu.name) && this.age==stu.age;
}

public String getName()
{
    return this.name;
}
public int getAge()
{
    return this.age;
}
public String toString()
{
    return name+","+age;
}

}
class Demo1
{
public static void main(String[] args)
{
ArrayList list = new ArrayList();

    list.add(new Student("zhangsan",23));
    list.add(new Student("lisi",21));
    list.add(new Student("wangwu",26));
    list.add(new Student("lisi",21));

    //姓名年龄相同的认为是同一个对象,从集合中去除掉
    ArrayList list2 = quChu(list);

    list2.remove(new Student("lisi",21));//删除也是依据boolean equals(Object obj)

    Iterator ite = list2.iterator();
    while(ite.hasNext())
    {
        sop(ite.next());
    }
}
public static ArrayList  quChu(ArrayList list)
{
    ArrayList list2 = new ArrayList();
    for(int i=0;i<list.size();i++)
    {
        Object obj = list.get(i);
        if(!list2.contains(obj))//contains方法是依据 boolean equals(Object obj)
        {
            list2.add(obj);
        }
    }
    return list2;
}

public static void sop(Object obj)
{
    System.out.println(obj);
}

}`

二.HashSet去除重复元素

HashSet底层使用的数据结构是哈希表,HashSet是无序的,它的实现原理是先判断对象的哈希值,如果相同再比较值是否相同,如果不同则直接添加。
保证对象的唯一原理:int hashCode() boolean equals(Object obj),在添加对象将该对象的哈希值和集合中已有对象的哈希值进行比较,如果哈希值都不相同,那么直接把该对象加入集合,如果出现哈希值相同的,那么再调用equals方法,只有equals方法返回true才认为是相同的对象,不加入集合。
所以我们要重写hashCode()方法,保证具有相同值的不同对象有相同的哈希值,这样才会通过equals()方法判断值是否相同,判断两个元素是否相同。代码如下:

`import java.util.*;
class Student
{
    private String name;
    private int age;

    Student(){}
    Student(String name,int age)
    {
        this.name = name;
        this.age = age;
    }
    //重写hashCode()方法,保证保证具有相同值的不同对象有相同的哈希值
    public int hashCode()
    {
        return name.hashCode()+age*36;
    }
    //重写equals()方法,判断两个对象的值是否相同
    public boolean equals(Object obj)
    {
        if(!(obj instanceof Student))
            throw new RuntimeException("类型不对");
        Student stu = (Student)obj;
        return this.name.equals(stu.name)&&this.age==stu.age;
    }


    public String getName()
    {
        return this.name;
    }
    public int getAge()
    {
        return this.age;
    }
    public String toString()
    {
        return name+","+age;
    }
}`  
`class Demo3 
{
    public static void main(String[] args) 
    {
        HashSet hs = new HashSet();
        //姓名年龄相同的认为是同一个对象,不能加入集合
        hs.add(new Student("zhangsan",23));
        hs.add(new Student("lisi",21));
        hs.add(new Student("wangwu",26));
        hs.add(new Student("zhangsan",23));

        sop(hs.contains(new Student("lisi",21)));//也是依据int hashCode()   boolean equals(Object obj)

        hs.remove(new Student("lisi",21));//也是依据int hashCode()   boolean equals(Object obj)

        sop(hs);
    }

    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
}`

三.TreeSet的两种排序方式

TreeSet具有自动排序功能,按照自然顺序排序。

`class Demo4 
{
    public static void main(String[] args) 
    {
        TreeSet ts = new TreeSet();
        //在添加时就已经进行排序了
        //因为String实现了Comparable接口中的 int compareTo(Object obj)方法
        //集合是依据字符串中的这个方法int compareTo(Object obj)来排序的
        ts.add("zwoeiuroie");
        ts.add("abcedf");// "abcedf".compareTo("zwoeiuroie")
        ts.add("wowieur");//"wowieur".compareTo("zwoeiuroie")  "wowieur".compareTo("abcedf")

        sop(ts);
    }

    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
}`

当我们需要对自定义对象进行排序时,就需要自定义一种排序方式了,通常有两种方式。
第一种方式:实现comparable接口,重写compareTo()方法

class Student implements Comparable
{
    private String name;
    private int age;

    Student(){}
    Student(String name,int age)
    {
        this.name = name;
        this.age = age;
    }

    public int compareTo(Object obj)
    {
        if(!(obj instanceof Student))
            throw new ClassCastException();
        Student stu = (Student)obj;
        int num = this.age-stu.age;//根据年龄从小到大排序

        return num==0?this.name.compareTo(stu.name):num;

    }
    public String getName()
    {
        return this.name;
    }
    public int getAge()
    {
        return this.age;
    }
    public String toString()
    {
        return name+","+age;
    }
}

如果comparable的排序方式不是我们需要的,自定义比较方式。因为我们不能轻易改动源代码,需要重写一种排序方式。
第二种方式:定义一个类实现comparator接口,并重写compare()方法,并将该类的对象作为TreeSet构造函数的参数传入。

class ComByName implements Comparator
{
    public int compare(Object obj1,Object obj2)
    {
        if(!(obj1 instanceof Student))
            throw new ClassCastException("类型转换异常");
        if(!(obj2 instanceof Student))
            throw new ClassCastException("类型转换异常");

        Student stu1 = (Student)obj1;
        Student stu2 = (Student)obj2;

        int num = stu1.getName().compareTo(stu2.getName());
        return num==0?stu1.getAge()-stu2.getAge():num;
    }
}
class Demo5 
{
    public static void main(String[] args) 
    {   
        ComByName cbn = new ComByName();//创建自定义的排序方式对象
        TreeSet ts = new TreeSet(cbn);//再创建集合对象时就得确定排序方式
        //自定义的排序方式优先被使用
        ts.add(new Student("zhangsan",23));
        ts.add(new Student("lisi",21));//new Student("lisi",21).compareTo(new Student("zhangsan",23))
        ts.add(new Student("wangwu",26));
        ts.add(new Student("pengfei",20));
        ts.add(new Student("zhaosi",23));

        sop(ts);
    }

    public static void sop(Object obj)
    {
        System.out.println(obj);
    }
}

当两种方式都存在时,优先使用comparator方式。

总结:人生中的第一次,写的有点挫,哈哈……,共同努力!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值