Java集合框架【二容器[LinkedList容器类、Set接口]】

小灰灰 2024-03-31 10:21 291阅读 0赞

文章目录

  • 一 LinkedList容器类
    • 1.1 LinkedList的使用(List接口)
    • 1.2 Linked的使用(非List标准)
    • 1.4 LinkedList源码分析
  • 二 Set接口
    • 2.1 Set接口特点
    • 2.2 HashSet容器类
      • 2.2.1 Hash算法原理
      • 2.2.2 HashSet的例子
      • 2.2.3 HashSet存储特征分析
    • 2.3 TreeSet容器类
    • 2.4 通过元素自身实现比较规则
    • 2.5 通过比较器实现比较规则
  • 三 单例集合使用例子
    • List实现
    • Set实现

一 LinkedList容器类

  • LinkedList底层用双向链表实现的存储。
  • 特点:查询效率低,增删效率高,线程不安全双向链表也叫双链表,是链表的一种,它的每个数据节点中都有两个指针,分别指向前一个节点和后一个节点。所以,从双向链表中的任意一个节点开始,都可以很方便地找到所有节点。
    在这里插入图片描述

    class Node {

    1. E item;
    2. Node<E> next;
    3. Node<E> prev;

    }

1.1 LinkedList的使用(List接口)

  • Linked实现了List接口,所以LinkedList是具备List的存储特征的【有序、可重复】

    public class LInkedListTest {

    1. public static void main(String[] args) {
    2. LinkedList<String> list = new LinkedList<>();
    3. list.add("a");
    4. list.add("b");
    5. list.add("c");
    6. list.add("a");
    7. for(String s :list) {
    8. System.out.println(s);
    9. }
    10. }

    }

在这里插入图片描述

1.2 Linked的使用(非List标准)














































方法 说明
void addFirst(E e) 将指定元素插入到开头
void add Last(E e) 将指定元素插入到结尾
getFirst() 返回此列表的第一个元素
getLast() 返回此列表的最后一个元素
removeFirst() 移除此列表中的第一个元素,并返回这个元素
removeLast() 移除此列表中的最后一个元素,并返回这个元素
E pop() 从此列表所表示的堆栈处弹出一个元素,等效于removeFirst
voidpush(E e) 将元素推入此列表所表示的堆栈这个等效于addFisrt(E e)
booleanisEmpty() 判断列表是否包含元素,如果不包含元素则返回true

1.4 LinkedList源码分析

  • 节点类

    private static class Node {

    1. E item;
    2. Node<E> next;
    3. Node<E> prev;
    4. Node(Node<E> prev, E element, Node<E> next) {
    5. this.item = element;
    6. this.next = next;
    7. this.prev = prev;
    8. }
    9. }

二 Set接口

  • Set接口继承自Collection,Set接口中没有新增方法,方法和Collection保持完全一致。我们在前面通过List学习的方法,在Set中仍然适用。因此,学习Set的使用将没有任何难度。

2.1 Set接口特点

  • Set特点:无序、不可重复无序指Set中的元素没有索引,我们只能遍历查找;不可重复指不允许加入重复的元素。更确切地讲,新元素如果和Set中某个元素通过equals()方法对比为true,则只能保留一个。
  • Set常用的实现类有:HashSet、TreeSet等。

2.2 HashSet容器类

  • Hashset是一个没有重复元素的集合,不保证元素的顺序。而且HashSet允许有null元素。HashSet是采用哈希算法实现,底层实际是用HashMap实现的(HashSet本质就是一个简化版的HashMap),因此,查询效率和增删效率都比较高。

2.2.1 Hash算法原理

  • Hash算法也称之为散列算法
    在这里插入图片描述

2.2.2 HashSet的例子

  1. /**
  2. * @author 缘友一世
  3. * date 2022/11/23-9:03
  4. */
  5. public class HashSetTest {
  6. public static void main(String[] args) {
  7. Set<String> set = new HashSet<>();
  8. set.add("a");
  9. set.add("d");
  10. set.add("b");
  11. set.add("a");
  12. //获取元素,在set容器中没有索引,没有对应的get方法。
  13. for(String s:set) {
  14. System.out.println(s);
  15. }
  16. boolean flag = set.remove("d");
  17. System.out.println(flag);
  18. for(String s:set) {
  19. System.out.println(s);
  20. }
  21. System.out.println(set.size());
  22. }
  23. }

在这里插入图片描述

2.2.3 HashSet存储特征分析

  • Hashset是一个不保证元素的顺序且没有重复元素的集合,是线程不安全的。Hashset允许有null元素

    1. 无序:

      • 在HashSet中底层是使用HashMap存储元素的。
      • HashMap底层使用的是数组与链表实现元素的存储。
      • 元素在数组中存放时,并不是有序存放的也不是随机存放的,而是对元素的哈希值进行运算决定元素在数组中的位置。
    2. 不重复:

      • 当两个元素的哈希值进行运算后得到相同的在数组中的位置时,会调用元素的equals()方法判断两个元素是否相同。如果元素相同则不会添加该元素,如果不相同则会使用单向链表保存该元素。

    /**

    • @author 缘友一世
    • date 2022/11/23-9:11
      */
      public class Users {

      private String userName;
      private int userAge;

      public Users() {

      }

      public Users(String userName, int userAge) {

      1. this.userName = userName;
      2. this.userAge = userAge;

      }

      public String getUserName() {

      1. return userName;

      }

      public void setUserName(String userName) {

      1. this.userName = userName;

      }

      public int getUserAge() {

      1. return userAge;

      }

      public void setUserAge(int userAge) {

      1. this.userAge = userAge;

      }

      @Override
      public int hashCode() {

      1. int result=userName !=null ? userName.hashCode():0;
      2. result=31*result+userAge;
      3. return result;

      }

      @Override
      public boolean equals(Object o) {

      1. if(this==o) return true;
      2. if(o==null || getClass()!=o.getClass()) return false;
      3. Users users = (Users) o;
      4. if(userAge!=users.userAge) return false;
      5. return userName!=null ? userName.equals(users.userName):false;

      }

      @Override
      public String toString() {

      1. return "Users{" +
      2. "userName='" + userName + '\'' +
      3. ", userAge=" + userAge +
      4. '}';

      }
      }

    class Test {

    1. public static void main(String[] args) {
    2. HashSet<Users> set1 = new HashSet<>();
    3. Users aaa = new Users("aaa", 19);
    4. Users bbb = new Users("aaa", 19);
    5. set1.add(aaa);
    6. set1.add(bbb);
    7. for(Users user:set1) {
    8. System.out.println(user);
    9. }
    10. }

    }

在这里插入图片描述

2.3 TreeSet容器类

  • TreeSet是一个可以对元素进行排序的容器底层实际是用TreeMap实现的,***内部维持了一个简化版的TreeMap,通过key来存储Set的元素。***TreeSet内部需要对存储的元素进行排序,因此,我们需要给定排序规则。
  • 排序规则实现方式

    • 通过元素自身实现比较规则
    • 通过比较器指定比较规则

    /**

    • @author 缘友一世
    • date 2022/11/23-9:30
      */
      public class TreeSetTest {

      public static void main(String[] args) {

      1. TreeSet<String> set = new TreeSet<>();
      2. set.add("c");
      3. set.add("a");
      4. set.add("b");
      5. set.add("1");
      6. for(String str:set) {
      7. System.out.println(str);
      8. }

      }
      }

在这里插入图片描述
在这里插入图片描述

2.4 通过元素自身实现比较规则

  • 在元素自身实现比较规则时,需要实现Comparable接口中的compareTo方法,该方法中用素定义比较规则。TreeSet通过调用该方法来完成对元素的排序处理。

    /**

    • @author 缘友一世
    • date 2022/11/23-12:53
      */
      public class SortTest {

      public static void main(String[] args) {

      1. TreeSet<Users2> set1 = new TreeSet<>();
      2. Users2 aaa = new Users2("aaa", 19);
      3. Users2 ccc = new Users2("ccc", 17);
      4. Users2 bbb = new Users2("bbb", 19);
      5. set1.add(aaa);
      6. set1.add(bbb);
      7. set1.add(ccc);
      8. for(Users2 user:set1) {
      9. System.out.println(user);
      10. }

      }
      }
      class Users2 implements Comparable {

  1. private String userName;
  2. private int userAge;
  3. public Users2() {
  4. }
  5. public Users2(String userName, int userAge) {
  6. this.userName = userName;
  7. this.userAge = userAge;
  8. }
  9. public String getUserName() {
  10. return userName;
  11. }
  12. public void setUserName(String userName) {
  13. this.userName = userName;
  14. }
  15. public int getUserAge() {
  16. return userAge;
  17. }
  18. public void setUserAge(int userAge) {
  19. this.userAge = userAge;
  20. }
  21. @Override
  22. public int hashCode() {
  23. int result=userName !=null ? userName.hashCode():0;
  24. result=31*result+userAge;
  25. return result;
  26. }
  27. @Override
  28. public boolean equals(Object o) {
  29. if(this==o) return true;
  30. if(o==null || getClass()!=o.getClass()) return false;
  31. Users2 users = (Users2) o;
  32. if(userAge!=users.userAge) return false;
  33. return userName!=null ? userName.equals(users.userName):false;
  34. }
  35. @Override
  36. public String toString() {
  37. return "Users{" +
  38. "userName='" + userName + '\'' +
  39. ", userAge=" + userAge +
  40. '}';
  41. }
  42. @Override
  43. public int compareTo(Users2 o) {
  44. if(this.userAge>o.getUserAge()) {
  45. return 1;
  46. }
  47. if(this.userAge==o.getUserAge()) {
  48. return this.userName.compareTo(o.getUserName());
  49. }
  50. return -1;
  51. }
  52. }

在这里插入图片描述

2.5 通过比较器实现比较规则

  • 通过比较器定义比较规则时,我们需要单独创建一个比较器,比较器需要实现Comparator接口中的compare方法来定义比较规则。
  • 在实例化TreeSet时将比较器对象交给TreeSet来完成元素的排序处理。此时元素自身就不需要实现比较规则了。

    /**

    • @author 缘友一世
    • date 2022/11/23-13:24
      */
      class Test {

      public static void main(String[]args){

      1. TreeSet<student> set = new TreeSet<>(new ComparatorTest());
      2. student ooo = new student("ooo", 18);
      3. student aaa = new student("aaa", 22);
      4. student sss = new student("sss", 22);
      5. set.add(ooo);
      6. set.add(aaa);
      7. set.add(sss);
      8. for(student x:set) {
      9. System.out.println(x);
      10. }

      }
      }
      public class ComparatorTest implements Comparator {

      //定义比较规则

      @Override
      public int compare(student o1, student o2) {

      1. if(o1.getAge()>o2.getAge()) {

      //升序

      1. return 1;
      2. }else if(o1.getAge()==o2.getAge()) {
      3. return o1.getName().compareTo(o2.getName());
      4. }
      5. return -1;

      }
      }
      class student {

      private String name;
      private int age;

      public student() {

      }

      public student(String name, int age) {

      1. this.name = name;
      2. this.age = age;

      }

      public String getName() {

      1. return name;

      }

      public void setName(String name) {

      1. this.name = name;

      }

      public int getAge() {

      1. return age;

      }

      public void setAge(int age) {

      1. this.age = age;

      }

      @Override
      public boolean equals(Object o) {

      1. if (this == o) return true;
      2. if (o == null || getClass() != o.getClass()) return false;
      3. student student = (student) o;
      4. return age == student.age && Objects.equals(name, student.name);

      }

      @Override
      public int hashCode() {

      1. return Objects.hash(name, age);

      }

      @Override
      public String toString() {

      1. return "student{" +
      2. "name='" + name + '\'' +
      3. ", age=" + age +
      4. '}';

      }
      }

在这里插入图片描述

三 单例集合使用例子

  • 生成1-10之间的随机数(1-10),将不重复的10个随机数放到容器中

List实现

  1. /**
  2. * @author 缘友一世
  3. * date 2022/11/23-13:36
  4. */
  5. public class SetDemo {
  6. public static void main(String[] args) {
  7. ArrayList<Integer> list = new ArrayList<>();
  8. while(true) {
  9. int num=(int)(Math.random()*10+1);
  10. if(!list.contains(num)) {
  11. list.add(num);
  12. }
  13. if(list.size()==10) {
  14. break;
  15. }
  16. }
  17. for(Integer x:list) {
  18. System.out.println(x);
  19. }
  20. }
  21. }

在这里插入图片描述

Set实现

  1. /**
  2. * @author 缘友一世
  3. * date 2022/11/23-13:36
  4. */
  5. public class SetDemo {
  6. public static void main(String[] args) {
  7. HashSet<Integer> set = new HashSet<>();
  8. while(true) {
  9. //set容器是不允许有重复元素的,所以不需要
  10. int num=(int)(Math.random()*10+1);
  11. set.add(num);
  12. if(set.size()==10) {
  13. break;
  14. }
  15. }
  16. for(Integer i:set) {
  17. System.out.println(i);
  18. }
  19. }
  20. }

在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,291人围观)

还没有评论,来说两句吧...

相关阅读