【愚公系列】2023年10月 Java教学课程 048

编程入门 行业动态 更新时间:2024-10-07 22:20:58

【<a href=https://www.elefans.com/category/jswz/34/1769546.html style=愚公系列】2023年10月 Java教学课程 048"/>

【愚公系列】2023年10月 Java教学课程 048

🏆 作者简介,愚公搬代码
🏆《头衔》:华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,阿里云专家博主,腾讯云优秀博主,掘金优秀博主,51CTO博客专家等。
🏆《近期荣誉》:2022年CSDN博客之星TOP2,2022年华为云十佳博主等。
🏆《博客内容》:.NET、Java、Python、Go、Node、前端、IOS、Android、鸿蒙、Linux、物联网、网络安全、大数据、人工智能、U3D游戏、小程序等相关领域知识。
🏆🎉欢迎 👍点赞✍评论⭐收藏

文章目录

  • 🚀一、Set集合
    • 🔎1.Set集合
      • 🦋1.1 Set集合概述和特点
      • 🦋1.2 Set集合的使用
    • 🔎2.HashSet集合
      • 🦋2.1 HashSet集合概述和特点
      • 🦋2.2 HashSet集合基本使用
      • 🦋2.3 哈希值
      • 🦋2.4 哈希表结构
      • 🦋2.5 案例
    • 🔎3.LinkedHashSet集合
      • 🦋3.1 LinkedHashSet集合概述和特点
      • 🦋3.2 LinkedHashSet集合基本使用
    • 🔎4.TreeSet集合
      • 🦋4.1 TreeSet集合概述和特点
      • 🦋4.2 TreeSet集合基本使用
      • 🦋4.3 自然排序Comparable的使用
      • 🦋4.4 自定义排序规则
      • 🦋4.5 两种比较方式总结
  • 🚀感谢:给读者的一封信


🚀一、Set集合

🔎1.Set集合

🦋1.1 Set集合概述和特点

Set是Java中的一个集合接口,它的特点是:

  1. 不允许重复元素:Set集合中不允许存储重复的元素,如果添加重复元素,新值将被忽略;
  2. 无序存储:Set集合中元素的顺序是未指定的,元素的插入顺序与取出顺序可能不同;
  3. 元素可为null:Set集合可以包含null元素。

Set集合的主要实现类有HashSet、TreeSet和LinkedHashSet,它们的区别在于内部实现方式和迭代器的顺序不同:

  1. HashSet:HashSet通过哈希表实现,元素无序存储,迭代器顺序未指定;
  2. TreeSet:TreeSet采用红黑树实现,元素按照大小排序,支持自然排序和定制排序;
  3. LinkedHashSet:LinkedHashSet内部使用HashMap来实现,元素按照插入顺序存储,迭代器顺序与插入顺序相同。

总之,Set集合是一种不允许重复元素的无序集合。使用Set集合能够高效地处理元素的查找和去重操作。

🦋1.2 Set集合的使用

import java.util.HashSet;
import java.util.Set;public class SetExample {public static void main(String[] args) {Set<String> set = new HashSet<>();// 添加元素到Set集合中set.add("apple");set.add("banana");set.add("orange");set.add("apple"); // 添加重复元素// 遍历Set集合中的元素for (String s : set) {System.out.println(s);}// 判断Set集合是否包含某个元素System.out.println(set.contains("grape"));  // falseSystem.out.println(set.contains("apple"));  // true// 删除Set集合中的元素set.remove("banana");// 清空Set集合中的所有元素set.clear();// 判断Set集合是否为空System.out.println(set.isEmpty());  // true}
}

输出结果为:

orange
banana
apple
false
true

可以看到,Set集合可以很方便地添加、删除、查找、清空元素。同时,由于Set集合的特点,最终只输出三个元素,重复元素被自动去重了。

🔎2.HashSet集合

🦋2.1 HashSet集合概述和特点

HashSet是Java集合框架中的一种实现类,它实现了Set接口,底层以哈希表(散列表)的形式存储数据,具有以下特点:

  1. 无序性:元素在集合中没有固定的位置,不保证遍历顺序和插入顺序相同。

  2. 不允许重复元素:HashSet中只能存储唯一的元素,如果添加重复元素,将自动被覆盖或忽略。

  3. 元素可以为null:HashSet可以存储null元素,但只能存储一个null元素。

  4. 高效性:HashSet的底层实现是哈希表,查找、插入和删除元素的效率都很高,时间复杂度为O(1)。

需要注意的是,在使用HashSet存储自定义的类型时,需要重写equals()和hashCode()方法,以保证正确性。

🦋2.2 HashSet集合基本使用

HashSet是Java中常用的集合类之一,它实现了Set接口,可以存储不重复的元素。HashSet内部使用哈希表来存储元素,可以快速进行插入、删除和查找操作。下面是HashSet集合的基本应用:

  1. 创建HashSet集合

可以使用无参构造函数创建一个空的HashSet集合。

HashSet<String> set = new HashSet<>();
  1. 添加元素到HashSet集合

可以使用add方法向HashSet集合添加元素,如果元素已经存在,则不会被添加。

set.add("apple");
set.add("banana");
set.add("orange");
  1. 判断HashSet集合是否包含某个元素

可以使用contains方法判断HashSet集合是否包含某个元素。

boolean contains = set.contains("apple");
  1. 从HashSet集合中删除某个元素

可以使用remove方法从HashSet集合中删除某个元素。

set.remove("apple");
  1. 遍历HashSet集合

可以使用for-each循环遍历HashSet集合。

for(String item: set) {System.out.println(item);
}
  1. 获取HashSet集合的大小

可以使用size方法获取HashSet集合的大小。

int size = set.size();

注意:HashSet集合是无序的,因此遍历HashSet集合时元素的顺序不确定。

🦋2.3 哈希值

哈希值是将任意长度的数据映射为固定长度的数据(通常是一个整数),该固定长度的数据就是哈希值。哈希值具有以下特点:

  1. 相同的输入一定产生相同的输出。

  2. 不同的输入尽可能产生不同的输出。

  3. 不同的输入可能产生相同的输出,这种情况称为哈希冲突。

在Java中,哈希值通常是用整数表示的,可以通过对象的hashCode方法获取对象的哈希值。下面是一个示例:

public class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}@Overridepublic int hashCode() {return Objects.hash(name, age);}
}public class Main {public static void main(String[] args) {Person person = new Person("Tom", 20);int hashCode = person.hashCode();System.out.println(hashCode);}
}

在上面的示例中,Person类重写了hashCode方法,使用Objects类的hash方法来计算哈希值,该方法会自动将多个属性进行混合计算,从而避免了哈希冲突的问题。可以通过调用hashCode方法获取Person对象的哈希值。

🦋2.4 哈希表结构

HashSet是一个基于哈希表实现的Set集合,它是Java集合框架中Set接口的实现类之一。在JDK1.7版本中,HashSet的实现方式是使用哈希表,它是通过一个数组来实现的,每个数组元素都是一个单向链表的头结点,单向链表中存储的是具有相同哈希码的元素。

HashSet的主要设计思路是:将元素根据哈希值分布到数组的不同位置上,这样可以通过哈希值快速地访问元素,提高了查找、插入和删除操作的效率。

实现原理:

  1. 创建HashSet对象时,会创建一个初始的数组,数组的长度默认为16,当数组长度不足时,会自动扩容。

  2. 将添加的元素先计算哈希值,然后根据哈希值%数组长度得到该元素在数组中的下标位置。

  3. 如果该位置为空,则将元素添加到该位置;如果该位置已经有元素,则遍历该位置上的链表,判断该元素是否已经存在,如果已经存在,则不再添加;否则将元素添加到链表的末尾。如果链表长度超过阈值(默认为8),则将链表转换为红黑树进行存储,这样在查找、删除等操作时可以更快速的定位元素。

  4. 当元素个数超过数组长度的0.75倍时,会触发扩容操作,将数组长度加倍,并重新计算元素在数组中的位置。

  5. 当元素被删除时,同样需要根据哈希值找到元素在数组中的位置,如果该位置上只有一个元素,则直接删除;如果该位置上有多个元素,则需要遍历链表或者红黑树,找到需要删除的元素。

HashSet的实现过程比较复杂,但是它的查找、插入和删除操作都是常数级别的,因此在大规模数据操作时,HashSet比较高效。

下面是JDK1.8版本HashSet的实现原理解析:

  1. HashSet是基于HashMap实现的,其内部维护了一个HashMap对象,HashMap的键存储HashSet中的元素,HashMap的值则是一个常量对象(DUMMY)。

  2. HashSet中的元素是无序的,是根据元素的hashCode值来确定元素在HashMap中的存储位置,并使用链表和红黑树解决哈希冲突。在JDK1.8中,当链表长度超过8时,链表会自动转化为红黑树,以提高查询效率。

  3. HashSet中的元素不允许重复,是根据元素的equals方法来判断两个元素是否相等。如果两个元素相等,则后面添加的元素会覆盖前面的元素。

  4. HashSet支持添加、删除、查找、遍历等操作,其时间复杂度与HashMap的相同,即O(1)。

HashSet是一种基于HashMap实现的无序、不重复元素集合,可以快速地进行添加、删除、查找和遍历操作。

🦋2.5 案例

  • 案例需求

    • 创建一个存储学生对象的集合,存储多个学生对象,使用程序实现在控制台遍历该集合
    • 要求:学生对象的成员变量值相同,我们就认为是同一个对象
  • 代码实现

    学生类

    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;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;if (age != student.age) return false;return name != null ? name.equals(student.name) : student.name == null;}@Overridepublic int hashCode() {int result = name != null ? name.hashCode() : 0;result = 31 * result + age;return result;}
    }
    

    测试类

    public class HashSetDemo02 {public static void main(String[] args) {//创建HashSet集合对象HashSet<Student> hs = new HashSet<Student>();//创建学生对象Student s1 = new Student("林青霞", 30);Student s2 = new Student("张曼玉", 35);Student s3 = new Student("王祖贤", 33);Student s4 = new Student("王祖贤", 33);//把学生添加到集合hs.add(s1);hs.add(s2);hs.add(s3);hs.add(s4);//遍历集合(增强for)for (Student s : hs) {System.out.println(s.getName() + "," + s.getAge());}}
    }
    
  • 总结

    ​ HashSet集合存储自定义类型元素,要想实现元素的唯一,要求必须重写hashCode方法和equals方法

🔎3.LinkedHashSet集合

🦋3.1 LinkedHashSet集合概述和特点

LinkedHashSet是Java中继承自HashSet的一种集合,它与HashSet的不同点在于,它可以保持元素插入的顺序。具体特点如下:

  1. 继承自HashSet,实现了Set接口,因此元素无重复且无序。
  2. 内部实现采用哈希表和双向链表结合的方式,保证了元素的插入顺序。
  3. 迭代器遍历时,按照元素插入的顺序进行遍历。
  4. 可以存储null元素。
  5. 由于内部维护了一个双向链表,因此在迭代过程中可以高效地执行插入和删除操作。

LinkedHashSet继承了HashSet的元素去重和快速查找特点,并且保证了元素的插入顺序,因此适用于需要保留元素插入顺序的业务场景下。

🦋3.2 LinkedHashSet集合基本使用

LinkedHashSet是HashSet的一个变体,它通过链表维护元素插入的顺序。这意味着遍历的顺序是元素插入的顺序,而不是元素的哈希码顺序。

LinkedHashSet中的元素具有唯一性,即集合中不包含重复的元素。与HashSet不同,LinkedHashSet允许null元素。

使用LinkedHashSet需要先创建LinkedHashSet对象,然后可以使用以下方法进行操作:

  • add(Object o):向集合中添加元素。
  • remove(Object o):从集合中移除元素。
  • contains(Object o):判断集合中是否包含指定元素。
  • size():返回集合中元素的数量。
  • clear():清空集合中的所有元素。
  • iterator():返回集合中元素的迭代器,可以用于遍历集合中的元素。

以下是LinkedHashSet的基本使用示例:

import java.util.LinkedHashSet;public class Main {public static void main(String[] args) {// 创建一个LinkedHashSet对象LinkedHashSet<String> set = new LinkedHashSet<>();// 往集合中添加元素set.add("A");set.add("B");set.add("C");set.add("D");set.add("E");set.add(null);// 遍历集合中的元素for (String str : set) {System.out.println(str);}// 判断集合中是否包含指定元素System.out.println(set.contains("A"));// 从集合中移除元素set.remove("B");// 清空集合中的所有元素set.clear();// 返回集合中元素的数量System.out.println(set.size());}
}

🔎4.TreeSet集合

🦋4.1 TreeSet集合概述和特点

TreeSet是Java中的一个有序集合类,它内部使用一棵红黑树来维护元素的顺序。TreeSet中的元素按照自然顺序排列(或者按照指定的比较器规则)。

TreeSet的主要特点包括:

  1. 有序性:TreeSet中元素是有序排列的,可以通过迭代器按照元素顺序遍历集合。

  2. 独一无二:TreeSet中不允许有重复元素。如果插入一个已经存在的元素,则会覆盖之前的元素。

  3. 可排序性:TreeSet中元素必须是可比较的,否则会抛出ClassCastException异常。

  4. 快速访问:使用TreeSet可以快速查找一个元素,时间复杂度为O(log n)。

需要注意的是,TreeSet不是线程安全的,如果多个线程同时访问TreeSet,则需要进行同步处理。

🦋4.2 TreeSet集合基本使用

Java中TreeSet是一个基于红黑树的实现,可以实现自动排序和去重功能。下面是TreeSet集合的基本使用:

1.创建TreeSet集合:

Set<Integer> set = new TreeSet<>();

2.添加元素:

set.add(1);
set.add(2);
set.add(3);

3.遍历集合:

for(Integer num : set){System.out.println(num);
}

4.判断集合是否包含某个元素:

if(set.contains(2)){System.out.println("包含2");
}

5.删除集合中的元素:

set.remove(2);

6.获取集合大小:

int size = set.size();

7.清空集合:

set.clear();

需要注意的是,要使用TreeSet集合存储自定义对象,必须要实现Comparable接口并重写compareTo方法,用于排序。否则会抛出ClassCastException异常。例如:

class Student implements Comparable<Student>{private String name;private int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic int compareTo(Student o) {//按照年龄从小到大排序return this.age - o.age;}//省略getter和setter方法
}Set<Student> set = new TreeSet<>();
set.add(new Student("张三",20));
set.add(new Student("李四",18));
set.add(new Student("王五",22));for(Student stu : set){System.out.println(stu.getName()+" "+stu.getAge());
}

🦋4.3 自然排序Comparable的使用

  • 案例需求

    • 存储学生对象并遍历,创建TreeSet集合使用无参构造方法
    • 要求:按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
  • 实现步骤

    1. 使用空参构造创建TreeSet集合
      • 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序的
    2. 自定义的Student类实现Comparable接口
      • 自然排序,就是让元素所属的类实现Comparable接口,重写compareTo(T o)方法
    3. 重写接口中的compareTo方法
      • 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
  • 代码实现

    学生类

    public class Student implements Comparable<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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Student o) {//按照对象的年龄进行排序//主要判断条件: 按照年龄从小到大排序int result = this.age - o.age;//次要判断条件: 年龄相同时,按照姓名的字母顺序排序result = result == 0 ? this.namepareTo(o.getName()) : result;return result;}
    }
    

    测试类

    public class MyTreeSet2 {public static void main(String[] args) {//创建集合对象TreeSet<Student> ts = new TreeSet<>();//创建学生对象Student s1 = new Student("zhangsan",28);Student s2 = new Student("lisi",27);Student s3 = new Student("wangwu",29);Student s4 = new Student("zhaoliu",28);Student s5 = new Student("qianqi",30);//把学生添加到集合ts.add(s1);ts.add(s2);ts.add(s3);ts.add(s4);ts.add(s5);//遍历集合for (Student student : ts) {System.out.println(student);}}
    }
    

🦋4.4 自定义排序规则

TreeSet是按照元素的自然顺序进行排序的,如果需要自定义排序规则,则需要实现Comparator接口。

下面是一个示例代码,演示了如何在TreeSet中使用自定义的排序规则:

import java.util.*;class Employee {private int id;private String name;private int age;public Employee(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}public int getId() {return id;}public String getName() {return name;}public int getAge() {return age;}
}class EmployeeComparator implements Comparator<Employee> {public int compare(Employee e1, Employee e2) {return e1.getName()pareTo(e2.getName());}
}public class Main {public static void main(String[] args) {TreeSet<Employee> employees = new TreeSet<>(new EmployeeComparator());Employee emp1 = new Employee(1, "John", 25);Employee emp2 = new Employee(2, "Alex", 30);Employee emp3 = new Employee(3, "David", 35);Employee emp4 = new Employee(4, "Mark", 28);employees.add(emp1);employees.add(emp2);employees.add(emp3);employees.add(emp4);for(Employee emp : employees) {System.out.println(emp.getName());}}
}

在上面的示例代码中,EmployeeComparator类实现了Comparator接口,并覆盖了它的compare方法。在compare方法中,我们按照员工的姓名来进行排序。

然后,在主方法中,我们创建了一个TreeSet对象,并传入了EmployeeComparator实例作为构造函数的参数。这样就可以使用自定义的排序规则来排序了。

最后,我们遍历TreeSet中的元素,并输出了它们的姓名,这里按照自定义的排序规则进行了排序。

🦋4.5 两种比较方式总结

  • 两种比较方式小结
    • 自然排序: 自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序
    • 比较器排序: 创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序
    • 在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,必须使用比较器排序
  • 两种方式中关于返回值的规则
    • 如果返回值为负数,表示当前存入的元素是较小值,存左边
    • 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存
    • 如果返回值为正数,表示当前存入的元素是较大值,存右边

🚀感谢:给读者的一封信

亲爱的读者,

我在这篇文章中投入了大量的心血和时间,希望为您提供有价值的内容。这篇文章包含了深入的研究和个人经验,我相信这些信息对您非常有帮助。

如果您觉得这篇文章对您有所帮助,我诚恳地请求您考虑赞赏1元钱的支持。这个金额不会对您的财务状况造成负担,但它会对我继续创作高质量的内容产生积极的影响。

我之所以写这篇文章,是因为我热爱分享有用的知识和见解。您的支持将帮助我继续这个使命,也鼓励我花更多的时间和精力创作更多有价值的内容。

如果您愿意支持我的创作,请扫描下面二维码,您的支持将不胜感激。同时,如果您有任何反馈或建议,也欢迎与我分享。

再次感谢您的阅读和支持!

最诚挚的问候, “愚公搬代码”

更多推荐

【愚公系列】2023年10月 Java教学课程 048

本文发布于:2024-02-14 02:32:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1761518.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:愚公   课程   系列   Java

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!