• Java集合框架(set)


    set继承自collection接口,其子类和子接口如下:

    set的共同特性:不能添加相同的元素,通常无法记住元素添加的顺序

    1.HashSet类

    判断两元素相同的标准:1.equals方法返回true,2.hashCode的值相等

    将元素添加进hashSet的时候,如果重写了equals方法,那么hashcode方法也应该重写,他们应该保持一致

    尽量不要修改集合元素中参与计算equals和hashcode的实例变量,否则可能导致HashSet无法正确操作这些元素,比如下面这种情况

    class R {
        int count;
        public R(int count) {
            this.count = count;
        }
        public String toString() {
            return "R[" + count + "]";
        }
        public boolean equals(Object obj) {
            if (this == obj) {
                return true;
            }
            if (obj != null && obj.getClass() == R.class) { //注意,这个实现使R对象都是equals
                return true;
            }
            return false;
        }
        public int hashCode() {
            return this.count;
        }
    }
    
    public class HashSetTest2 {
        public static void main(String[] args) {
            HashSet hs = new HashSet();
            hs.add(new R(5));
            hs.add(new R(-3));
            hs.add(new R(9));
            hs.add(new R(-2));
            System.out.println(hs); //[R[5], R[9], R[-3], R[-2]]
            
            Iterator it = hs.iterator();
            R first = (R)it.next();
            first.count = -3;
            System.out.println(hs); //[R[-3], R[9], R[-3], R[-2]]
            
            hs.remove(new R(-3));
            System.out.println(hs);//[R[-3], R[9], R[-2]]
            System.out.println(hs.contains(new R(-3))); //false
            System.out.println(hs.contains(new R(5))); //true
        
            
            
            /*这样的结果可以看出
             * 我们找到值为5的对象,将其值替换为-3之后,这个set中就有两个完全一样的元素了
             * 删除值为-3的元素时,先通过hashCode找到了原来-3的元素,将其删除
             * 
             * 但是结果显示hashset中并没有-3,却有5
             * 因为根据我们实现的equals方法,所有R对象都是equal的
             * 但是hashcode值却是根据count的值算出来的
             * 第一个元素的hashcode值是根据5算出来的,所以这个元素被hashset认为与R(5)相通,与R(-3)不同。
             * 
             * */
        }
    }
    View Code

    2.TreeSet类

    此类可保证集合元素处于排序状态(红黑树实现),与HashSet相比,添加了如下方法

    自然排序:

    添加到TreeSet中的对象必须已经实现了Comparable接口的 compareTo方法,并且必须是同一种类型的对象

    TreeSet判断两个对象是否相等的标准是:compareTo方法返回值为0则相等,否则不相等。

    class Z implements Comparable {
        int age;
        public Z(int age) {
            this.age = age;
        }
        
        @Override
        public boolean equals(Object obj) {
            // TODO Auto-generated method stub
            return true;
        }
        @Override
        public int compareTo(Object o) {
            // TODO Auto-generated method stub
            return 1;
        }
    }
    
    /*重要:
     * 在TreeSet中添加元素的时候要保证equals方法和Comparable接口的结果一致
     * 否则就会出现下面的情况,尽管两个元素equal,但是TreeSet仍然认为他们两个是不同的元素
     * 存的时候就成了“一个元素的两个引用”
     * */
    public class TreeSetTest2 {
        public static void main(String[] args) {
            TreeSet ts = new TreeSet();
            Z z1 = new Z(6);
            ts.add(z1);
            System.out.println(ts.add(z1));
            System.out.println(ts);
            ((Z)(ts.first())).age = -1;
            System.out.println(((Z)(ts.last())).age);
        }
    }
    View Code

    尽量不要修改TreeSet中的可变对象中的实例变量,一旦这个变量影响了compareTo方法的返回值,该集合中的元素的顺序就会不一致

    定制排序:

    如果需要实现定制排序,则需要在创建TreeSet对象的时候,使一个Comparator对象与TreeSet集合关联起来。

    Comparator接口中有一个 compare(T o1, T o2)方法,返回正数说明o1大于o2,负数则是小于,0就是等于。

    class M
    {
        int age;
        public M(int age)
        {
            this.age = age;
        }
        public String toString()
        {
            return "M[age:" + age + "]";
        }
    }
    public class TreeSetTest4
    {
        public static void main(String[] args) 
        {
            TreeSet ts = new TreeSet(new Comparator()
            {
                //根据M对象的age属性来决定大小
                public int compare(Object o1, Object o2)
                {
                    M m1 = (M)o1;
                    M m2 = (M)o2;
                    return m1.age > m2.age ? -1
                        : m1.age < m2.age ? 1 : 0;
                }
            });    
            ts.add(new M(5));
            ts.add(new M(-3));
            ts.add(new M(9));
            System.out.println(ts);
        }
    }
    View Code

     3.EnumSet类

    enum Season
    {
        SPRING,SUMMER,FALL,WINTER
    }
    public class EnumSetTest
    {
        public static void main(String[] args) 
        {
            //创建一个EnumSet集合,集合元素就是Season枚举类的全部枚举值
            EnumSet es1 = EnumSet.allOf(Season.class);
            //输出[SPRING,SUMMER,FALL,WINTER]
            System.out.println(es1);
            //创建一个EnumSet空集合,指定其集合元素是Season类的枚举值。
            EnumSet es2 = EnumSet.noneOf(Season.class); 
            //输出[]
            System.out.println(es2);
            //手动添加两个元素
            es2.add(Season.WINTER);
            es2.add(Season.SPRING);
            //输出[SPRING,WINTER]
            System.out.println(es2);
            //以指定枚举值创建EnumSet集合
            EnumSet es3 = EnumSet.of(Season.SUMMER , Season.WINTER); 
            //输出[SUMMER,WINTER]
            System.out.println(es3);
            EnumSet es4 = EnumSet.range(Season.SUMMER , Season.WINTER); 
            //输出[SUMMER,FALL,WINTER]
            System.out.println(es4);
            //新创建的EnumSet集合的元素和es4集合的元素有相同类型,
            //es5的集合元素 + es4集合元素 = Season枚举类的全部枚举值
            EnumSet es5 = EnumSet.complementOf(es4); 
            //输出[SPRING]
            System.out.println(es5);
        }
    }
    View Code
  • 相关阅读:
    寒假周总结一
    1657. Determine if Two Strings Are Close
    1656. Design an Ordered Stream
    695. Max Area of Island (BFS)
    695. Max Area of Island (DFS)
    Daily Coding Problem: Problem #713
    939. Minimum Area Rectangle
    259. 3Sum Smaller
    29. Divide Two Integers
    16. 3Sum Closest
  • 原文地址:https://www.cnblogs.com/qianbixin/p/6052364.html
Copyright © 2020-2023  润新知