Java入门Day10:Set集合-创新互联

1. Set 接口

1.无序(添加和取出的顺序不一致)
2.不允许重复元素,所以最多包含一个null
3.JDK API中的Set接口的实现类有很多,主要有TreeSet和HashSet两个

创新互联是少有的成都网站设计、网站制作、外贸营销网站建设、营销型企业网站、微信小程序、手机APP,开发、制作、设计、外链、推广优化一站式服务网络公司,2013年开创至今,坚持透明化,价格低,无套路经营理念。让网页惊喜每一位访客多年来深受用户好评
  • Set接口的实现类的对象(Set接口对象),不能存活重复的元素,。
  • 存放数据是无序的,添加和取出的顺序无关,但每次取出的顺序是一样的,下次取出的顺序不会改变。
  • 底层是由数组加链表的形式实现的。
  • Set的遍历可以使用迭代器。
  • Set的常用方法和List相似。
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Demo01 {public static void main(String[] args) {Set set = new HashSet();
        set.add("jack");
        set.add("lucy");
        set.add("john");
        set.add("jack");
        set.add(null);
        System.out.println(set);

        //迭代器遍历
        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {Object next = iterator.next();
            System.out.println(next);
        }

        //增强for循环
        for (Object o: set) {System.out.println(o);
        }
        //set接口对象,不能通过索引来获取,因此不能用普通for循环来遍历
    }
}
2. HashSet 集合 2.1 底层实现
  • HashSet的底层其实HashMap
  • HashSet的元素的顺序是hash后索引的结果
  • 先获取元素的哈希值(hashCode方法)
    对哈希值进行运算,得到一个索引值,即为要存放在哈希表中的索引。
    如果该位置没有其他元素,直接存放;
    如果有其他元素,则进行equals判断,如果相等,则不再添加。如果不相等,则以链表的方式添加。
    当一条链表的元素个数超过TREEIFY_THRESHOLD(默认是8),并且table的大小>=MIN_TREEIFY_CAPACITY(默认是64),就会进行树化(红黑树)。
    当每次扩容时,会重新进行hash排序,node空间在数组中的排序会变化。
    向hashset加入一个元素时,Node加入table,size就增加1,并不是占用12个数组元素才扩容。
2.2 例子
  • 定义一个Employee类,该类包含:private成员属性name,age,birthday(MyDate类型),其中birthday为MyDate类型(属性包括:year,month,day),要求:
    1.创建3个Employee放入HashSet中
    2.当name和birthday的值相同时,认为是相同员工,不能添加到HashSet集合中
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public class Demo01 {public static void main(String[] args) {Employee employee1 = new Employee("曹操",42,new Employee.MyDate(112,4,7));
        Employee employee2 = new Employee("刘备",33,new Employee.MyDate(121,7,9));
        Employee employee3 = new Employee("刘备",33,new Employee.MyDate(121,7,9));

        HashSet hashSet = new HashSet();
        hashSet.add(employee1);
        hashSet.add(employee2);
        hashSet.add(employee3);
        System.out.println(hashSet);
        System.out.println(hashSet);
    }

static class Employee{private String name;
        private int age;
        private MyDate birthday;

    public Employee(String name, int age, MyDate birthday) {this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    public String getName() {return name;
    }

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

    public int getAge() {return age;
    }

    public void setAge(int age) {this.age = age;
    }

    public MyDate getBirthday() {return birthday;
    }

    public void setBirthday(MyDate birthday) {this.birthday = birthday;
    }

    @Override
    public boolean equals(Object o) {if (this == o) return true;
        if (!(o instanceof Employee)) return false;
        Employee employee = (Employee) o;
        return age == employee.age && Objects.equals(name, employee.name) && Objects.equals(birthday, employee.birthday);
    }

    @Override
    public int hashCode() {return Objects.hash(name, age, birthday);
    }

    @Override
    public String toString() {return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                '}';
    }

    public static class MyDate {int year;
        int month;
        int day;
        public MyDate(int year, int month, int day) {this.year = year;
            this.month = month;
            this.day = day;
        }

        @Override
        public boolean equals(Object o) {if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            MyDate myDate = (MyDate) o;
            return year == myDate.year && month == myDate.month && day == myDate.day;
        }

        @Override
        public int hashCode() {return Objects.hash(year, month, day);
        }

        @Override
        public String toString() {return  year +
                    "年" + month +
                    "月" + day +
                    "日";
        }
    }
}
}
3. LinkedHashSet 集合

在LinkHashSet中维护了一个hash表和双向链表,不同于hashSet中的链表,LinkHashSet中的链表是可以跨数组元素变量空间的双向链表
双向链表是有head和tail的,它的顺序是我们添加元素的顺序,这样我们遍历LinkedHashSet时,就能使遍历顺序和插入顺序一致。

3.1 例子
  • 建立一个Car类,包含name,price两种属性,如果name和price一样,则认为是相同元素,就不能添加。
import java.util.LinkedHashSet;
import java.util.Objects;

public class Demo01 {public static void main(String[] args) {LinkedHashSet linkedHashSet = new LinkedHashSet();
        linkedHashSet.add(new Car("A8",700000));
        linkedHashSet.add(new Car("A8",700000));
        linkedHashSet.add(new Car("C100",1100000));
        linkedHashSet.add(new Car("AE86",100000));
        System.out.println(linkedHashSet);

    }
}
class Car{private String name;
    private int price;

    public Car(String name, int price) {this.name = name;
        this.price = price;
    }

    public String getName() {return name;
    }

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

    public int getPrice() {return price;
    }

    public void setPrice(int price) {this.price = price;
    }

    @Override
    public boolean equals(Object o) {if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Car car = (Car) o;
        return price == car.price && Objects.equals(name, car.name);
    }

    @Override
    public int hashCode() {return Objects.hash(name, price);
    }

    @Override
    public String toString() {return "Car{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


分享标题:Java入门Day10:Set集合-创新互联
网站链接:http://pwwzsj.com/article/idggh.html