Java中的HashSet和TreeSet

Java中的HashSet类中存放的对象不能重复,怎么定义是否重复就得开发人员自己来自定,比如定义一个Person类,你可以人为两个名字相同的人,表示是一个人,那么HashSet中就不会存放两个名为”Tom”的对象。

一般来说如果要把一类对象放入HashSet中我们一般需要重写其hashCode方法和equals方法。在我们使用HashSet时,被放入对象的hashCode就会得到调用,判断已经存在的对象是否与增加的对象有一样的hashCode,如果不一致,直接加进去,如果一只,需要再进行equals方法的比较,equals方法如果返回为true表示已经加进去了,不再加入。(因为:对于两个对象,如果用equals方法比较返回false,那么这个两个对象的hashCode值不要求不一样(可以相同也可以不同))。

举一个HashSet的栗子:

import java.util.HashSet;
import java.util.Iterator;

public class HashSetTest {
    public static void main(String[] args) {
        HashSet<Student> set = new HashSet<Student>();
        set.add(new Student("小明"));
        set.add(new Student("小李"));
        set.add(new Student("小明"));

        Iterator iter = set.iterator();
        while(iter.hasNext()) {
            System.out.println(iter.next());
        }
    }


}

class Student{
    private String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object obj) {
        if(this==obj) {
            return true;
        }
        if(obj!=null&&obj instanceof Student) {
            Student student = (Student)obj;
            if(student.name.equals(this.name)) {
                return true;
            }else {
                return false;
            }
        }
        return false;
    }
    @Override
    public int hashCode() {
        return this.name.hashCode();
    }

    @Override
    public String toString() {
        return this.name;
    }
}

在上面的程序中,如果名字相同那么我们就认为其为同一个对象,就不再加入HshSet中。
结果为:

小明
小李

TreeSet是一种自带排序的set。

当我们把元素放入set中时,要么这个元素所对应的类实现了Comparable接口,要么就得提供一个实现了Comparator接口的实现类。

  • 实现了Comparable接口的类作为被加入set的元素。
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class ComparableTest {
    public static void main(String[] args) {
        Set<User> set = new TreeSet<User>();
        set.add(new User(1,"Tom"));

        set.add(new User(3,"Lucy"));

        set.add(new User(2,"Bob"));

        Iterator<User> iter = set.iterator();
        while(iter.hasNext()) {
            System.out.println(iter.next());
        }
    }

}

class User implements Comparable<User>{

    private int userId;

    private String name;


    public User(int userId, String name) {
        this.userId = userId;
        this.name = name;
    }

    public int compareTo(User user) {
        return this.userId-user.userId;
    };

    @Override
    public String toString() {
        return this.userId+"-----"+this.name;
    }
}

结果为:

1-----Tom
2-----Bob
3-----Lucy
  • 提供一个实现了Comparator接口的实现类,作为比较器。
import java.util.Comparator;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class CompatorTest {

    public static void main(String[] args) {
        Set<Person> set = new TreeSet<Person>(new PersonComparator());
        set.add(new Person(16,"Tom"));
        set.add(new Person(17,"Bob"));
        set.add(new Person(16,"Andrew"));
        set.add(new Person(19,"Jerry"));
        set.add(new Person(20,"Lucy"));

        for(Iterator<Person> iter = set.iterator();iter.hasNext(); ) {
            System.out.println(iter.next());
        }
    }

}

class Person{

    private int age;

    private String name;

    public Person(int age, String name) {
        super();
        this.age = age;
        this.name = name;
    }

    @Override
    public String toString() {
        return name+" : "+age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

class PersonComparator implements Comparator<Person>{
    @Override
    public int compare(Person o1, Person o2) {
        return o2.getName().compareTo(o1.getName());
    }

}

结果为:

Tom : 16
Lucy : 20
Jerry : 19
Bob : 17
Andrew : 16

Collections类中提供了许多静态的方法来操作实现了Collection接口类的对象。
举个例子

import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;

public class CollectionsTest {

    public static void main(String[] args) {

        LinkedList<String> list = new LinkedList<String>();
        list.add("Tom");
        list.add("Lucy");
        list.add("Andrew");
        list.add("Bob");
        //返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序.
        Comparator comp = Collections.reverseOrder();

        Collections.sort(list, comp);

        for(Iterator<String> iter = list.iterator();iter.hasNext(); ) {
            System.out.println(iter.next());
        }
    }

}

结果为:

Tom
Lucy
Bob
Andrew
  • HashMap遍历的两种方式:
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HashMapEx2 {
    public static void main(String[] args) {
        Map<String,String> map = new HashMap<String,String>();
        map.put("a","A");
        map.put("b","B");
        map.put("c","C");
        map.put("d","D");
        /**
         * 方法一通过拿到key的集合,遍历集合,然后取出相应的value。
         */
        System.out.println("方法一-------------------------------------");
        Set<String> set = map.keySet();
        for(Iterator<String> iter = set.iterator();iter.hasNext(); ) {
            String key = iter.next();
            System.out.println(key+"--------"+map.get(key));
        }

        System.out.println("方法二----------------------------------------");
        /**
         * 方法通过得到所有entry的集合然后遍历每一个entry然后得到相应的key和value。
         */
        Set<Map.Entry<String, String>> set2 =map.entrySet();
        for(Iterator<Map.Entry<String, String>> iter2 = set2.iterator();iter2.hasNext();) {
            Map.Entry<String, String> entry = iter2.next();
            String key =entry.getKey();
            String value = entry.getValue();
            System.out.println(key+"---"+value);
        }
    }



}

运行结果为:

方法一-------------------------------------
a--------A
b--------B
c--------C
d--------D
方法二----------------------------------------
a---A
b---B
c---C
d---D
  • TreeMap类似于TreeSet是一种带排序的map,它是给key排序。放入TreeMap的元素要么实现了Comparable接口要么给TreeMap一个实现了Comparator接口的比较器。

猜你喜欢

转载自blog.csdn.net/light_blue_love/article/details/79777745