Java从入门到放弃17—set集合HashSetLinkedHashSetTreeSet

    xiaoxiao2022-07-05  177

    Java从入门到放弃17—set集合/HashSet/LinkedHashSet/TreeSet

    01 set集合

    set集合元素唯一(不包含重复元素),无序(存取顺序不一致)

    02 HashSet集合

    HashSet 底层数据结构是哈希表,是元素为链表的数组,具有链表和数组的特点。HashSet不是线程安全的,集合元素可以是null。

    初始容量16,加载因子0.75。

    HashSet集合能够保证元素的唯一性是依靠元素类重写hashCode()方法和equals()方法来保证的,如果元素类不重写该方法,则存储该元素的集合不保证元素唯一。

    HashSet底层用的是HashMap来存元素的。

    hashCode()决定索引位置,如果该方法返回一个死值,会造成碰撞次数太多,效率太低。合理地重写hashCode()能有效减少碰撞次数。(对象之间对比的次数)

    //以学生类为例,重写hashCode方法 @Override public int hashCode() { return this.name.hashCode() + this.age * 11; } @Override public int hashCode() { return Objects.hash(name, age); } //String和integer类对hashCode和equals方法已经重写

    alt+insert选择equals和hashcode快速重写


    03 LinkerHashSet集合

    LinkedHashSet 底层数据结构是链表和哈希表,元素有序且唯一,链表保证了元素有序(存取顺序一致),哈希表保证了元素唯一。 public class MyTest { public static void main(String[] args) { LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>(); linkedHashSet.add("A"); linkedHashSet.add("B"); linkedHashSet.add("D"); linkedHashSet.add("E"); linkedHashSet.add("C"); linkedHashSet.add("E"); linkedHashSet.add("C"); linkedHashSet.add("E"); linkedHashSet.add("C"); for (String s : linkedHashSet) { System.out.print(s+"\t"); } } } //运行结果 A B C D E C

    04 TreeSet集合

    TreeSet 底层数据结构是二叉数,元素唯一,最大的特点是能够对元素进行排序。TreeSet不允许存null值TreeSet 排序方式分为自然排序和比较器排序。具体使用哪种排序由调用的构造方法决定。空参构造使用的是自然排序,有参构造使用的比较器排序。 TreeSet() 构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。 TreeSet(Comparator < ? super E > comparator) 构造一个新的空 TreeSet,它根据指定比较器进行排序。 自然排序要求元素必须实现一个Comparable接口并重写里面的compareTo方法。(String重写了compareTo方法,返回的是正负零。) class M implements Comparable{ @Override public int compareTo(Object o) { //按需求重写逻辑 return 0; }@override } 自然排序示例: public class MyTest {//测试类 public static void main(String[] args) { //按照学生的年龄大小来排序 Student s1 = new Student("John", 21); Student s2 = new Student("Snow", 22); Student s3 = new Student("John", 21); TreeSet<Student> treeSet = new TreeSet<>();//使用无参构造则采用自然排序方法 treeSet.add(s1); treeSet.add(s2); treeSet.add(s3); for (Student student : treeSet) { System.out.println(student); } } } //运行结果:Student{name='John', age=21} Student{name='Snow', age=22} public class Student implements Comparable<Student> {// 元素类 必须实现Comparable接口 private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } 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; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public int compareTo(Student s) {//重写compareTo方法 //比较逻辑按照年龄大小来排序 int num1 = this.age - s.age; //年龄相同时并不能说明是同一个对象,要继续比较姓名 int num2 = num1 == 0 ? this.name.compareTo(s.name) : num; return num2; } } 比较器排序要求元素实现Comparator接口和compare方法,可以采用匿名内部类来做 public class MyTest{//测试类 public static void main(String[] args){ Student stu1 = new Student("John",18); Student stu2 = new Student("Edwards",23); student stu3 = new Student("jack",22); TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>() { @Override public int compare(Student s1,Student s2){ int num1=s1.getAge()-s2.getAge(); int num2=num1==0?s1.getName().compareTo(s2.getName()):num1; return num2; } });//有参构造 treeSet.add(stu1); treeSet.add(stu2); treeSet.add(stu3); for(Student s : treeSet){ System.out.println(s); } } } //运行结果:Student{name='John', age=18} Student{name='jack', age=22} Student{name='Edwards', age=23} public class Student { private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } 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; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
    案例练习1 //随机产生十个不重复的,范围在0-20的数 public class Test{ public static void main(String[] args){ Random random=new Random(); LinkedSet<Integer> linkedSet = new LinkedSet<>(); while(linkedSet.size()<10){ int num = random.nextInt(20)+1; linkedSet.add(num); } System.out.println(set); } } 案例练习2 //去除list集合里的重复元素 public class MyTest5 { public static void main(String[] args) { ArrayList<Integer> integers = new ArrayList<>(); integers.add(12); integers.add(12); integers.add(12); integers.add(10); integers.add(11); integers.add(14); integers.add(16); integers.add(88); HashSet<Integer> integers1 = new HashSet<>(integers); System.out.println(integers1); } } 案例练习3 //需求:键盘录入3个学生信息(姓名, 语文成绩, 数学成绩, 英语成绩), 按照总分从高到低输出到控制台。 public class Student { private String name; private int chineseScore; private int mathScore; private int englishScore; public Student() { } public Student(String name, int chineseScore, int mathScore, int englishScore) { this.name = name; this.chineseScore = chineseScore; this.mathScore = mathScore; this.englishScore = englishScore; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getChineseScore() { return chineseScore; } public void setChineseScore(int chineseScore) { this.chineseScore = chineseScore; } public int getMathScore() { return mathScore; } public void setMathScore(int mathScore) { this.mathScore = mathScore; } public int getEnglishScore() { return englishScore; } public void setEnglishScore(int englishScore) { this.englishScore = englishScore; } //获取总分的方法 public int getTotalScore() { return this.chineseScore + mathScore + englishScore; } } //测试类 public class Test{ public static void main(String[] args){ TreeSet<Student> treeSet = new TreeSet<>(new Comparator<Student>(){ @override public int compare(Student s1,Student s2){ int num1=s1.getTotalScore()-s2.getTotalScore(); int num2=num1==0?s1.getName().compareTo(s2.getName()):num1; return num2; } }); int i=1; while(i<=3){ Scanner sc = new Scanner(System.in); System.out.println("请输入第" + i + "个学生的姓名"); String name = sc.nextLine(); student.setName(name); System.out.println("请输入" + name + "的语文成绩"); int yw = sc.nextInt(); System.out.println("请输入" + name + "的数学成绩"); int sx = sc.nextInt(); System.out.println("请输入" + name + "的英语成绩"); int yy = sc.nextInt(); Student stu = new Student(name,yw,sx,yy); treeSet.add(stu); } for(Student s : treeSet){ System.out.println(s.getName+"|"s.getChineseScore()+"|"+s.getMathScore()+"|"+s.getEnglishScore()+"|"+s.getTotalScore()) } } }
    最新回复(0)