Java Set的操作示例

Set 不能有重复的元素,且是无序的,要有空值也就只能有一个,因为它不允许重复。
Set接口中的方法和Collection一致。

HashSet

HashSet 内部数据结构是哈希表 ,是不同步的。

  • 如何保证该集合的元素唯一性呢?
    是通过对象的hashCode()和equals()方法来保证对象唯一性的。
  • 如果对象的hashCode值不同,那么不用判断equals方法,就直接存储到哈希表中。
  • 如果对象的hashCode值相同,那么要再次判断对象的equals方法是否为true。
    如果为true,视为相同元素,不存。
    如果为false,那么视为不同元素,就进行存储。
  1. 如果hashcode函数返回一个定值,即所有对象的hashcode相同时,当尝试插入第二个数据(或以上)时,会发现程序还会去调用equals方法,并且该函数返回false时才回插入HashSet;当hashcode返回不同时会忽略equals函数并直接插入HashSet。
  2. 总结,HashSet先调用对象的hashcode函数来进行散列,当散列到不同位置时,则认为对象不相同且进行插入操作(不用判断equals函数);当散列到同一个位置才会调用对象的equals函数来进行比较,只当equals返回false则认为两个对象不相等才会进行插入操作,否则认为两个对象相同而不进行插入操作。
  3. 自定义对象,重载equals和hashcode时,应该保证两个对象的hashcode的比较结果 和 两个对象的equals函数比较结果,一样。

记住:
1. 如果元素要存储到HashSet集合中,必须覆盖hashCode方法和equals方法。
2. 一般情况下,如果自定义的类会产生很多对象,比如人,学生,书,通常都需要覆盖equals(),hashCode()方法,建立对象判断是否相同的依据。

如果HashSet不覆盖equals()和hashCode()方法的话,默认的是使用Object中的equals()和hashCode()方法。Object中的equals方法比较地址的,而不是比较内容,如果添加重复的对象,地址不同,就会认为没有重复的对象,所以比较对象是否相同,必须覆盖equals和hashCode方法

示例:

// 往HashSet集合中存储Person对象,如果姓名和年龄相同,视为同一个人,视为相同元素。

@Override
public boolean equals(Object obj) { // 判断Person的内容是否相同
    if(this == obj) //this只是否为Person自身对象
        return true;
    if(!(obj instanceof Person)){
        throw new ClassCastException("类型转化错误!");
    }
    Person p = (Person)obj;
    return this.name.equals(p.name) && this.age == p.age; //字符创name的内容相同吗,年龄相同吗
}

@Override
public int hashCode() { // 判断Person的hash值是否相同
    return name.hashCode()+ age;
}
HashSet hs = new HashSet();

hs.add(new Person("a",24));
hs.add(new Person("b",27));

Iterator it = hs.iterator();

while(it.hasNext()){
    Person p = (Person)it.next();
    System.out.println(p.getName()+"...."+p.getAge());
}

TreeSet

  使用TreeSet自然排序,如果存放的是自定义对象,必须实现Comparable接口,覆盖里面的compareTo方法,添加元素的时候会进行比较;如果添加的是字符串就不需要覆盖compareTo方法,因为字符串有自己的compareTo方法

public class Person implements Comparable{...}

// 以Person对象年龄进行排序,如果年龄相同,就按照姓名排序
@Override
public int compareTo(Object o) {
    if(!(o instanceof Person))
        throw new ClassCastException("类型转化错误");

    Person p = (Person)o;
    int temp = this.age-p.age;

    return temp==0 ? (this.name.compareTo(p.name)) : temp; // temp等于0表示年龄相等。
}
TreeSet ts = new TreeSet();

ts.add(new Person("zhangsan",28));
ts.add(new Person("lisi",21));
ts.add(new Person("zhouqi",29));
ts.add(new Person("zhaoliu",25));
ts.add(new Person("wangu",24));
ts.add(new Person("zhouqi",29));

Iterator it = ts.iterator();
while(it.hasNext()){
    Person p = (Person)it.next();
    System.out.println(p.getName()+":"+p.getAge());
}
public class Test {

    public static void main(String[] argv) {  
        TreeSet<String> ts = new TreeSet();

        ts.add("abc");
        ts.add("zaa");
        ts.add("aa");
        ts.add("nba");
        ts.add("abc");

        Iterator it = ts.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    } 
}

// 输出:
/*
aa
abc
nba
zaa
*/

使用TreeSet(Comparator< ? super E> comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。

/**
 * 创建了一个根据Person类的name进行排序的比较器。
 * 先按照姓名进行比较,如果姓名相同,再按照年龄进行比较
 */
public class ComparatorByName implements Comparator {

    @Override
    public int compare(Object o1, Object o2) {

        Person p1 = (Person)o1;
        Person p2 = (Person)o2;

        int temp = p1.getName().compareTo(p2.getName());
        // 姓名相同,再比较年龄
        return temp==0 ? p1.getAge()-p2.getAge(): temp;
    }

}
TreeSet<Person> ts = new TreeSet(new ComparatorByName());

ts.add(new Person("zhangsan",28));
ts.add(new Person("lisi",21));
ts.add(new Person("zhouqi",29));
ts.add(new Person("zhaoliu",25));
ts.add(new Person("wangu",24));

Iterator it = ts.iterator();
while(it.hasNext()){
    Person p = (Person)it.next();
    System.out.println(p.getName()+":"+p.getAge());
}
/* 
 * 对字符串进行长度排序,再比较内容
 */

public class TreeSetTest {

    public static void main(String[] args) {

        // 接口内部类
        TreeSet ts = new TreeSet(new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                int temp = o1.length() - o2.length();
                return temp==0 ? o1.compareTo(o2) : temp;
            }
        });

        ts.add("aaaaa");
        ts.add("zz");
        ts.add("nbaq");
        ts.add("cba");
        ts.add("abc");
        ts.add("abc");

        Iterator it = ts.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

// 输出:
/*
zz
abc
cba
nbaq
aaaaa
*/

转自:http://www.cnblogs.com/200911/p/3948436.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的SortedSet是一个接口,它继承自Set接口,其中的元素按照自然顺序或者指定的比较器进行排序。SortedSet中的元素必须实现Comparable接口或者在构造函数中提供指定的Comparator接口。 SortedSet接口中定义了以下常用方法: 1. first():返回SortedSet中的第一个元素。 2. last():返回SortedSet中的最后一个元素。 3. subSet(fromElement, toElement):返回SortedSet中从fromElement(包括)到toElement(不包括)之间的元素。 4. headSet(toElement):返回SortedSet中小于toElement的元素。 5. tailSet(fromElement):返回SortedSet中大于等于fromElement的元素。 6. comparator():返回用于排序的Comparator对象。 以下是一个示例代码,演示如何使用SortedSet接口: ```java import java.util.SortedSet; import java.util.TreeSet; public class SortedSetDemo { public static void main(String[] args) { SortedSet<String> set = new TreeSet<>(); set.add("apple"); set.add("banana"); set.add("orange"); set.add("pear"); System.out.println("SortedSet: " + set); SortedSet<String> subSet = set.subSet("banana", "pear"); System.out.println("SubSet: " + subSet); SortedSet<String> headSet = set.headSet("orange"); System.out.println("HeadSet: " + headSet); SortedSet<String> tailSet = set.tailSet("orange"); System.out.println("TailSet: " + tailSet); System.out.println("First: " + set.first()); System.out.println("Last: " + set.last()); } } ``` 输出结果: ``` SortedSet: [apple, banana, orange, pear] SubSet: [banana, orange] HeadSet: [apple, banana] TailSet: [orange, pear] First: apple Last: pear ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值