Java集合框架(二)之Set详解

本文详细解析了Java中Object类的equals()和hashCode()方法,以及HashSet和TreeSet集合的具体使用和原理。同时介绍了如何利用Collections类进行集合操作,包括排序、随机打乱顺序、获取最大值和最小值等常用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

-------android培训、java培训、期待与您交流! ----------

equals()和hashCode()方法详细解析

关于Object类的equals方法的特点:

a) 自反:x.equals(x)应该返回true

b) 对称性:x.equals(y)true,那么y.equalsx)也为true

c) 传递性:x.quals(y)true,并且y.equals(z)true,那么x.equals(z)也应该为true

d) 一致性:x.equals(y)的第一次调用为true,那么x.equals(y)的第二次,第三次,第n次调用也应该为true,前提条件是在比较之前没有修改x也没有修改y

e) 对于非空引用xx.equals(null)返回false

关于Object类的hashCode方法的特点:

a) Java应用的一次执行过程当中,对于同一个对象的hashCode方法的多次调用,他们应该返回同样的值(前提是该对象的信息没有发生变化)

b) 对于两个对象来说,如果使用equals方法比较返回true,那么这两个对象的hashCode值一定是相同的。

c) 对于两个对象来说,如果使用equals方法比较返回false,那么这两个对象的hashCode值不要求一定不同(可以相同,可以不同),但是如果不同则可以提高应用的性能。

d) 对于Object类来说,不同的Object对象的hashCode值是不同的(Object类的hashCode值表示的是对象的地址)

HashSet

我们在认识set集合看段代码:

publicclassHashSetTest {

      publicstaticvoid main(String[] args) {

       HashSet set=newHashSet();

       set.add("a");

       set.add("b");

       set.add("c");

       set.add("d");

       set.add("a");

       System.out.println(set);

  }

}

我们将看到打印结果是无序且只有一个a

我们现在再看看以下代码,来认识下HashSet里面放置的是什么对象?

import java.util.HashSet;

 

public class HashSetTest2 {

        publicstatic void main(String[] args) {

                  HashSetset=new HashSet();

                  set.add(newPeople("Tom"));

                  set.add(newPeople("Tom"));

                  set.add(newPeople("rose"));

                  

                  System.out.println(set);

                  set.clear();//清空之前结果

                  

                  System.out.println("---------------------");

                  Peoplep1=new People("zhangsan");

                  set.add(p1);

                  set.add(p1);

                  System.out.println(set);

                  set.clear();

                  

                  System.out.println("-------------");

                  Strings1=new String("java1");

                  Strings2=new String("java1");

                  set.add(s1);

                  set.add(s2);

                  System.out.println(set);//@1

   }

}

class People{

        Stringname;

        publicPeople(String name){

                  this.name=name;

        }

}

总结,当我们使用HashSet时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hash Code值是否与增加的对象的hashCode值一致;如果不一致,直接加进去;如果一致的话,再进行equals方法的比较,equals方法如果返回true,表示对象已经加进去了,就不会再增加新的对象,否则加进去。

这时我们知道,判断放进去的东西是不是一样,是由equalshashCode方法共同判断的。

如以上代码@1处,打印system.out.println(“hash code+s1.hashCoed==s2.hashCode;打印为真,所以不会放置HashSet集合中。

我们要知道,如果我们重写equals方法,那么也要重写hashCode方法,反之亦然。

例如以下例子:

import java.util.HashSet;

 

publicclassHashSetTest3 {

  publicstaticvoid main(String[] args) {

       HashSet set =newHashSet();

       set.add(new Student("张三"));

       set.add(new Student("张三"));

       System.out.println(set);

  }

 

}

class Student{

Stringname;

public Student(String name) {

  this.name=name;

}

publicinthashCode(){

  returnthis.name.hashCode();

}

publicboolean equals(Object o){

  if(this==o){

     returntrue;

  }

  if(o!=null&&oinstanceof Student){

     Studentstu =(Student)o;

     if(this.name==stu.name){

        returntrue;

     }

  }

  returnfalse;

}

}

 

我们也可以使用eclipse提供给我们的hashCodeequals重写方法,这里就不举例子了

我们要想取得Set集合里的元素,这里我们介绍下迭代器的概念

 

迭代器(Iterator

集合中的迭代器是个接口,是用来遍历集合的,用的频率相当高

Iterator<E>iterator():返回在此 set中的元素上进行迭代的迭代器。返回的元素没有特定的顺序(除非此 set是某个提供顺序保证的类的实例)。

接口迭代器有几种方法呢?我们最常用的两种方法:

a)      booleanhasNext():如果仍有元素可以迭代,则返回 true。(换句话说,如果 next返回了元素而不是抛出异常,则返回 true)。

b)      E next():返回迭代的下一个元素。

下面通过代码来看看具体用法:

import java.util.HashSet;

import java.util.Iterator;

 

publicclassIteratorTest {

  publicstaticvoid main(String[] args) {

     HashSetset=newHashSet();

     set.add("hello");

     set.add(" world");

     set.add(" welcome");

     

     Iteratorit=set.iterator();//使用迭代器方法

     while(it.hasNext()){  //判断是true,如果是一直循环。

        Stringstr=(String) it.next();//获得下个元素,并赋给String类型

        System.out.print(str);

     }

 

     //使用for循环来写

     System.out.println("----------------------");

    for(Iterator it1=set.iterator();it1.hasNext();){//最后什么++--都不用写

       String str=(String) it1.next();

       System.out.print(str);

      }

    }

}

 

TreeSet

TreeSet实现了sortedSet接口,sortedSetSet接口的子接口,TreeSet是具有排序的功能,默认是从小到大进行排序。我们来看看TreeSet的如下代码:

import java.util.TreeSet;

 

publicclassTreeSetTest1 {

  publicstaticvoid main(String[] args) {

     TreeSetset=newTreeSet();

     set.add("c");

     set.add("a");

     set.add("f");

     set.add("e");

     set.add("b");

     //打印[a, b, c, e, f]

     System.out.println(set);

  }

}

那么,我们如果要对集合类元素进行反向排序呢?这里我们就要实现Comparator接口,下面我们来看看如何将set集合进行反向排序呢?看如下代码

import java.util.Comparator;

import java.util.Iterator;

import java.util.TreeSet;

 

publicclassComparatTest {

  publicstaticvoidmain(String[] args) {

     TreeSetset=newTreeSet(new CompareFor());//根据TreeSet的另一种构造方法

     set.add("A");

     set.add("B");

     set.add("C");

     set.add("D");

     set.add("E");

     set.add("F");

     

     for(Iteratorit=set.iterator();it.hasNext();){

        Stringvalue=(String) it.next();

        System.out.println(value);

     }

}

}

 

class CompareForimplementsComparator{

 

  publicint compare(Object o1,Object o2) {

     Strings1=(String) o1;

     Strings2=(String) o2;

     return s2.compareTo(s1);//o2-o1=1(正整数),此处调用String类的compareTo方法

  }

}

 

Collections

Collection是一个接口,而加上一个sCollections类,那么这个类在集合中的作用是什么呢?这个类在就是对集合操作的一个类,就像Arrays类对数组的操作一样,下面我们来看看Collections在集合中是怎么使用的?

下面我们列举下Collections常用的方法:

a) 反向排序:publicstatic <T> Comparator<T> reverseOrder():返回一个比较器,它强行逆转指定比较器的顺序

b)排序:lic static <T> voidsort(List<T> list,Comparator<? super T> c):根据指定比较器产生的顺序对指定列表进行排序。

c)随机(打乱顺序):public static void shuffle(List<?> list):使用默认随机源对指定列表进行置换。所有置换发生的可能性都是大致相等的。

d)最大值:public static maxCollectionc):根据元素的自然顺序,返回给定 collection的最大元素

e)最小值:public static min(Collection c):根据指定比较器产生的顺序,返回给定 collection的最小元素

 

我们现在通过代码来看看这些方法是怎么用的:

import java.util.Collections;

import java.util.Comparator;

import java.util.Iterator;

import java.util.LinkedList;

 

publicclassCollectionsTest {

  publicstaticvoid main(String[] args) {

     LinkedListlist =newLinkedList();

     list.add(20);

     list.add(-8);

     list.add(-20);

     list.add(8);

     

     Comparatorr=Collections.reverseOrder();//使用Collection方法中反向排序

     Collections.sort(list,r);//排序方法

     for(Iteratorit=list.iterator();it.hasNext();){

        Integeri=(Integer) it.next();

        System.out.print(i+" ");

     }

     System.out.println();//换行

     System.out.println("--------------------------------");

     

     Collections.shuffle(list);

     for(Iteratorit=list.iterator();it.hasNext();){

        Integeri=(Integer) it.next();

        System.out.print(i+" ");

     }

     System.out.println();//换行

     System.out.println("----------------------");

     System.out.println("最大值"+Collections.max(list));

     System.out.println("最小值"+Collections.min(list));

  }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值