Java集合

Java集合

码农世界 2024-05-28 前端 70 次浏览 0个评论

单列集合

集合框架

Collection接口的使用

  1. 概述:单列集合的顶级接口

  2. 使用:

    • 创建:Collection 对象名 = new 实现类对象()
    • :泛型,决定了集合中能存储什么类型的数据,可以统一数据类型
    • 泛型中只能写引用数据类型,如果不写,默认Object类型,此时什么类型的数据都可以存储
    • 泛型细节:我们等号前面的泛型必须写,等号后面的泛型可以不写,jvm会根据前面的泛型推导出后面的泛型是什么

    • 常用方法:

      boolean add(E e):将给定的元素添加到当前集合中,返回的是Boolean类型
      boolean addAll(Collection c):将另一个集合元素添加到当前集合中(集合合并)
      void clear():清除集合中的所有元素
      boolean contains(Object o):判断当前集合中是否包含指定元素
      boolean isEmpty():判断当前集合中是否为空
      boolean remove(Object o):将指定的元素从集合中删除
      int size():返回集合中的元素个数
      Object[] toArray():把集合中的元素,存储到数组当中
      

List接口

  1. 概述:是Collection接口的子接口

  2. 常见的实现类:

    ArrayList、 LinkedList 、Vector

ArrayList集合

  1. 概述:ArrayList是List接口的实现类

  2. 特点:

    元素有序 -> 按照什么顺序存的就按照什么顺序取

    元素可重复

    有索引 -> 可以利用索引去操作元素

    线程不安全

  3. 数据结构:数组

  4. 常用方法:

    boolean add(E e) -> 将元素添加到集合当中,尾部添加
    void add(int index, E element) -> 在指定索引位置添加元素
    boolean remove (Objrct o) -> 删除指定的元素
    E remove(int index) -> 删除指定索引位置上的元素,返回的是被删除的元素
    E set(int index, E element) -> 将指定索引位置上的元素,修改成后面的element元素
    E get(int index) -> 根据索引获取元素
    int size() -> 获取集合元素个数
    
  5. 集合的遍历

import java.util.*;
public class hhh {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        System.out.println("=================");
        for (String s : list) {
            System.out.println(s);
        }
        System.out.println("=================");
        //遍历带有索引的快捷键:集合名.fori
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
    }
}

ArrayList构造方法:

ArrayList() 构造一个初始容量为10的空列表

ArrayList(int initialCapacity) 构造一个具有指定初始容量的空列表

注意:

不是一new底层就会创建一个初始容量为10的空列表,而是第一次add的时候

ArrayList底层会自动扩容 -> Arrays.copyOf -> 扩容1.5倍

LinkedList集合

  1. 概述:LinkedList是List接口的实现类

  2. 特点:

    元素有序

    元素可重复

    有索引 -> 这里有索引指的是有操作索引的方法,不代表本质上有索引

    线程不安全

  3. 数据结构:双向链表

  4. 方法:有大量直接操作首尾元素的方法

    public void addFirst(E e) -> 将指定元素插入此链表的开头
    public E removeFirst() -> 删除并返回此链表的第一个元素
    public void addLast(E e) -> 
    public E removeLast() -> 
    public E getFirst() -> 返回此列表的第一个元素
    public E getLast() -> 
    public E pop() -> 从此列表的堆栈中弹出一个元素,第一个
    public void push(E e) -> 将元素推入此列表所表示的堆栈,第一个
    public void isEmpty(E e) -> 判断列表是否为空
    
  5. LinkedList底层成员解释说明

    • LinkedKList底层成员

      transient int size = 0;元素个数

      transient Node first;第一个节点对象

      transient Node last;最后一个结点对象

    • Node代表的是节点对象

Vector集合

  1. 概述:Vector是List的实现接口

  2. 特点:

    元素有序

    有索引

    元素可重复

    线程安全

  3. 数据结构:数组

  4. 如果空参创造对象,数组初始容量为10,如果超出范围,自动扩容2倍

    如果有参创造对象,如果超出了范围,自动扩容,扩的是老数组长度 + 指定容量的增量

import java.util.Vector;
public class HashTable {
    public static void main(String[] args) {
        Vector strings = new Vector<>();
        strings.add("aa");
        strings.add("bb");
        for (String string : strings) {
            System.out.println(string)
        }
    }
}

Collections集合工具类

  1. 概述:集合工具类

  2. 特点:

    构造私有

    方法都是静态的

  3. 类名直接调用

  4. 常用方法与示例

import java.util.*;
public class hhh {
    public static void main(String[] args) {
        ArrayList list = new ArrayList<>();
        //static  boolean addAll(Collectionc, T...element) -> 批量添加元素
        Collections.addAll(list, "a", "e", "c", "d", "f", "g", "h");
        System.out.println(list);
        //static void shuffle(List list) -> 将集合中的元素顺序打乱
        Collections.shuffle(list);
        System.out.println(list);
        //static  void sort(List list) -> 将集合中的元素进行排序--> ASCII码表
        Collections.sort(list);
        System.out.println(list);
    }
}
  • 元素按指定规则排序
      static  void sort(List list, Comparator c) -> 将集合的元素按照指定规则排序
    
    • Comparator比较器
      2.  方法:
          int compare(T o1, T o2)
          	o1-o2 -> 升序
          	o2-o1 -> 降序
          
      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 int getAge() {
              return age;
          }
          public void setName(String name) {
              this.name = name;
          }
          public void setAge(int age) {
              this.age = age;
          }
          @Override
          public String toString() {
              return "student [name=" + name + ", age=" + age + "]";
          }
      }
      import java.util.ArrayList;
      import java.util.Collections;
      import java.util.Comparator;
      public class studentTest {
          public static void main(String[] args) {
              ArrayList stu = new ArrayList<>();
              stu.add(new student("zz",24));
              stu.add(new student("pp",29));
              stu.add(new student("qq",26));
      //        Collections.sort(stu);//报错,里面三个对象,不知道按照什么排序
               Collections.sort(stu,new Comparator() {
                   @Override
                   public int compare(student o1, student o2) {
                       return o1.getAge()-(o2.getAge());
                   }
               });
               System.out.println(stu);
          }
      }
      输出
          [student [name=zz, age=24], student [name=qq, age=26], student [name=pp, age=29]]
      
      • 接口:Comparable接口
        方法:
            int compareTo(T o) -> this-o(升序)  o-this(降序)
            
        public class student implements Comparable{
            private String name;
            private Integer score;
            public student(String name, Integer score) {
                this.name = name;
                this.score = score;
            }
            public String getName() {
                return name;
            }
            public void setName(String name) {
                this.name = name;
            }
            public Integer getScore() {
                return score;
            }
            public void setScore(Integer score) {
                this.score = score;
            }
            public String toString() {
                return "name: " + name + ", score: " + score;
            }
            @Override
            public int compareTo(student student) {
                return this.getScore() - student.getScore();
                //return this.score.compareTo(student.score);
            }
        }
        import java.util.ArrayList;
        import java.util.Collections;
        public class studentTest {
            public static void main(String[] args) {
                ArrayList students = new ArrayList<>();
                students.add(new student("pp",23));
                students.add(new student("py",24));
                students.add(new student("pt",28));
                students.add(new student("pg",26));
                System.out.println(students);
                Collections.sort(students);//已经知道怎么排列,因此不报错
                System.out.println(students);
            }
        }
        输出
            [name: pp, score: 23, name: py, score: 24, name: pt, score: 28, name: pg, score: 26]
        	[name: pp, score: 23, name: py, score: 24, name: pg, score: 26, name: pt, score: 28]
        
        • 拓展方法:Arrays中的静态方法
              static  List asList(T...a) -> 指定元素转存到list集合中
              
          import java.util.Arrays;
          import java.util.List;
          class erweishuzu {
              public static void main(String[] args) {
                  List list = Arrays.asList("整数", "天天", "哈哈", "密码");
                  System.out.println(list);//[整数, 天天, 哈哈, 密码]
              }
          }
          

          泛型

          1. 泛型<>

          2. 作用:统一数据类型,防止将来的数据转换异常

          3. 注意:

            泛型中的类型必须是引用数据类型

            如果泛型不写,默认类型为Object

          为什么使用泛型

          1. 从使用层面来说:统一数据类型,防止将来的数据类型转换异常
          import java.util.ArrayList;
          class erweishuzu {
              public static void main(String[] args) {
                  ArrayList list = new ArrayList();
                  list.add("1");
                  list.add(2);
                  list.add("abc");
                  list.add(true);
                  for(Object o : list){
                      String s = (String) o;
                      System.out.println(s.length()); //从第二个开始报错
                  }
              }
          }
          
          1. 从定义层面来看:定义带泛型的类、方法等,将来使用的时候给泛型确定什么类型,泛型就会变成什么类型,凡是涉及到泛型的都会变成确定的类型,代码更灵活

          泛型的定义

          1. 含有泛型的类
          1.定义:
              public class 类名{
                  
              }
          2.什么时候确定类型:new对象的时候确定类型
              
          import java.util.Arrays;
          public class erweishuzu {
                  Object[] obj = new Object[10];
                  int size;
                  public boolean add(E e){
                      obj[size] = e;
                      size++;
                      return true;
                  }
                  public E get(int index){
                      return (E)obj[index];
                  }
                  @Override
                  public String toString() {
                      return Arrays.toString(obj);
                  }
          }
          public class ptakaoshi {
              public static void main(String[] args) {
                  erweishuzu objecterweishuzu = new erweishuzu<>();
                  objecterweishuzu.add("aaa");
                  objecterweishuzu.add("bbb");
                  System.out.println(objecterweishuzu); //[aaa, bbb, null, null, null, null, null, null, null, null]
                  erweishuzu objecterweishuzu1 = new erweishuzu<>();
                  objecterweishuzu1.add(1);
                  objecterweishuzu1.add(2);
                  objecterweishuzu1.add(3);
                  System.out.println(objecterweishuzu1); //[1, 2, 3, null, null, null, null, null, null, null]
                  Integer ele = objecterweishuzu1.get(0);
                  System.out.println(ele); //1
              }
          }
          
          1. 含有泛型的方法
          1.格式:
              修饰符  返回值类型 方法名(E e)
          2.什么时候确定类型:调用的时候确定类型
              
          import java.util.ArrayList;
          public class erweishuzu {
              public static  void addAll(ArrayList list,E...e){
                  for(E e1 : e){
                      list.add(e1);
                  }
              }
          }
          import java.util.ArrayList;
          public class ptakaoshi {
              public static void main(String[] args) {
                  ArrayList objects = new ArrayList<>();
                  erweishuzu.addAll(objects,"a","b","c","d","e","f","g","h","i");
                  System.out.println(objects); //[a, b, c, d, e, f, g, h, i]
                  ArrayList list2 = new ArrayList<>();
                  erweishuzu.addAll(list2,1,2,3,4,5,6,7,8,9);
                  System.out.println(list2); //[1, 2, 3, 4, 5, 6, 7, 8, 9]
              }
          }
          
          1. 含有泛型的接口
          1.格式:
          	public interface 接口名{
              
          	}
          2.什么时候确定类型:
              在实现类的时候还没有确定类型,只能在new实现类的时候确定类型了 -> 比如:ArrayList
          	在实现类的时候直接确定类型了 -> 比如Scanner
          
          public interface Mylist {
              public boolean add(E e);
          }
          import java.util.Arrays;
          public class Mylist1  implements Mylist {
              Object[] obj = new Object[10];
              int size = 0;
              public boolean add(E e) {
                  obj[size] = e;
                  size++;
                  return true;
              }
              public E get(int index) {
                  return (E) obj[index];
              }
              public String toString(){
                  return Arrays.toString(obj);
              }
          }
          public class Text1 {
              public static void main(String[] args) {
                  Mylist1 list1 = new Mylist1<>();
                  list1.add("An");
                  list1.add("Bn");
                  System.out.println(list1);//[An, Bn, null, null, null, null, null, null, null, null]
              }
          }
          
          public interface MySca {
              E next();
          }
          public class Myscann implements MySca {
              @Override
              public String next() {
                  return "hhh";
              }
          }
          public class Text2 {
              public static void main(String[] args) {
                  Myscann myscann = new Myscann();
                  String result = myscann.next();
                  System.out.println(result); //hhh
              }
          }
          

          泛型的高级使用

          1. 泛型通配符
          import java.util.*;
          public class hhh {
              public static void main(String[] args) {
                  ArrayList list1 = new ArrayList<>();
                  list1.add("a");
                  list1.add("b");
                  ArrayList list2 = new ArrayList<>();
                  list2.add(1);
                  list2.add(2);
                  method(list1);
                  method(list2);
              }
              public static void method(ArrayList list) {
                  for(Object o : list) {
                      System.out.println(o);
                  }
              }
          }
          
          1. 泛型的上限下限
          1.作用:可以规定泛型的范围
          2.上限:
              格式:
              含义:?只能接收extends后面的本类类型以及子类类型
          3.下限:
          	格式:
              含义:?只能接收super后面的本类类型以及父类类型
          

          应用场景:

          1. 如果我们在定义类、方法、接口的时候,如果类型不确定,我们可以考虑定义含有泛型的类、方法、接口
          2. 如果类型不确定,但是能知道以后只能传递某个类的继承体系中的子类或者父类,就可以使用泛型的通配符

          Set集合

          Set接口属于Collection接口的另外一个子接口,并没有对Collection进行任何功能上的扩充,而且所有的set集合底层都是依靠Map实现的

          Set集合介绍

          1. Set和Map密切相关
          2. Map的遍历要先变成单列集合,只能变成Set集合

          HashSet集合的介绍和使用

          1. 概述:HashSet是Set接口的实现类

          2. 特点:

            元素唯一

            元素无序

            无索引

            线程不安全

          3. 数据结构:哈希表

            jdk8之前:哈希表 = 数组 + 链表

            jdk8之后:哈希表 = 数组 + 链表 + 红黑树(加入红黑树是为了查询快)

          4. 方法:和collection一样

          5. 遍历:增强for、迭代器

          import java.util.HashSet;
          import java.util.Iterator;
          public class koko1 {
              public static void main(String[] args) {
                  HashSet set = new HashSet<>();
                  set.add("一样");
                  set.add("会将");
                  set.add("雨哦");
                  System.out.println(set);
                  Iterator iterator = set.iterator();
                  while (iterator.hasNext()) {
                      System.out.println(iterator.next());
                  }
                  for (String s : set) {
                      System.out.println(s);
                  }
              }
          }
          

          LinkedHashSet集合的介绍和使用

          1. 概述:LinkedHashSet继承HashSet

          2. 特点:

            元素唯一

            元素有序

            无索引

            线程不安全

          3. 数据结构:哈希表 + 双向链表

          4. 使用:与父类一样

          import java.util.Iterator;
          import java.util.LinkedHashSet;
          public class koko1 {
              public static void main(String[] args) {
                  LinkedHashSet set = new LinkedHashSet<>();
                  set.add("一样");
                  set.add("会将");
                  set.add("雨哦");
                  System.out.println(set);
                  Iterator iterator = set.iterator();
                  while (iterator.hasNext()) {
                      System.out.println(iterator.next());
                  }
                  for (String s : set) {
                      System.out.println(s);
                  }
              }
          }
          

          TreeSet

          1. 概述:TreeSet是set的实现类

          2. 特点:

            对元素进行排序

            无索引

            不能存null

            线程不安全

            元素唯一

          3. 数据结构:红黑树

          构造:
              TreeSet() -> 构造一个新的空树集,根据其元素的自然顺序进行排序。-> ASCII
              TreeSet(Comparator comparator) -> 构造一个新的空树集,根据指定的比较器排序。
              
          public class Person {
              private String name;
              private int age;
              public Person(String name, int age) {
                  this.name = name;
                  this.age = age;
              }
              public String getName() {
                  return name;
              }
              public int getAge() {
                  return age;
              }
              public void setName(String name) {
                  this.name = name;
              }
              public void setAge(int age) {
                  this.age = age;
              }
              @Override
              public String toString() {
                  return "Person{" + "name=" + name + ", age=" + age + '}';
              }
          }
          import java.util.Comparator;
          import java.util.TreeSet;
          public class PersonText {
              public static void main(String[] args) {
                  TreeSet persons = new TreeSet<>(new Comparator() {
                      @Override
                      public int compare(Person o1, Person o2) {
                          return o1.getAge()-(o2.getAge());
                      }
                  });
                  persons.add(new Person("hh",16));
                  persons.add(new Person("jj",19));
                  persons.add(new Person("gg",12));
                  System.out.println(persons); 
                  //[Person{name=gg, age=12}, Person{name=hh, age=16}, Person{name=jj, age=19}]
              }
          }
          
          哈希值
          1. 概述:是由计算机计算出来的一个十进制数,可以看作是对象的地址值

          2. 获取对象的哈希值,使用的是Object中的方法

            public native int HashCode()
            
          3. 如果重写了hashCode方法,那计算的就是对象内容的哈希值了

          • 哈希值不一样,内容肯定不一样
          • 哈希值一样,内容也有可能不一样

          集合遍历方式

          迭代器

          基本使用
          1. 概述:Iterator接口

          2. 主要作用:遍历集合

          3. 获取:Collection中的方法:

            Iterator iterator()
            
          4. 方法:

            boolean hasNext() -> 判断集合中有没有下一个元素
                E next() -> 获取下一个元素
            
          import java.util.ArrayList;
          import java.util.Iterator;
          public class dieDai1 {
              public static void main(String[] args) {
                  ArrayList list = new ArrayList<>();
                  list.add("A");
                  list.add("B");
                  list.add("C");
                  list.add("D");
                  //获取迭代器对象
                  Iterator iterator  = list.iterator();
                  while (iterator.hasNext()) {
                      System.out.println(iterator.next());//A B C D
                  }
              }
          }
          
          迭代过程
          int cursor; //下一个元素索引位置
          int lastRet = -1; //上一个元素索引位置
          
          底层原理
          1.获取Iterator的时候怎么获取的:
          	Iterator iterator = list.iterator()
              Iterator是一个接口,等号右边是他的实现类对象,接收的是ArrayList中的内部类Itr对象
          

          注意:只有ArrayList使用迭代器的时候iterator接口才会指向Itr,其他的就不指向了

          并发修改异常
          import java.util.ArrayList;
          import java.util.Iterator;
          public class A1 {
              public static void main(String[] args) {
                  ArrayList list = new ArrayList<>();
                  list.add("A");
                  list.add("B");
                  list.add("C");
                  list.add("D");
                  Iterator iterator = list.iterator();
                  while (iterator.hasNext()) {
                      String s = iterator.next();
                      if("C".equals(s)){
                          list.add("e");
                      }
                  }
                  System.out.println(list);
              }
          }
          输出报错:
          Exception in thread "main" java.util.ConcurrentModificationException
          	at java.base/java.util.ArrayList$Itr.checkForComodification(ArrayList.java:1096)
          	at java.base/java.util.ArrayList$Itr.next(ArrayList.java:1050)
          	at PPPttt.A1.main(A1.java:15)
          

          迭代器内部维护了一个expectedModificationCount,即预期的操作次数,当集合的实际修改次数与这个计数不匹配时(当预期操作次数和实际操作次数不相等了),就会抛出ConcurrentModificationException(并发修改异常)

          使用迭代器迭代集合的过程中,不要随意修改集合长度,容易出现并发修改异常

          补充

          ArratList中的方法:ListIterator listIterator

          在Java中,ListIterator 是 Iterator 接口的一个扩展,专门为 List 接口的实现类提供额外的操作。ListIterator 允许程序员对列表进行双向迭代,即既可以向前迭代也可以向后迭代,这与只能单向迭代的普通 Iterator 不同。

          ArrayList 类实现了 List 接口,因此它提供了 listIterator() 方法来创建和返回一个 ListIterator 对象。

          • ListIterator 的特点:
            1. 双向迭代:ListIterator 可以调用 next() 方法来获取下一个元素,也可以调用 previous() 方法来获取上一个元素。
            2. 修改列表:ListIterator 允许在迭代过程中修改列表(通过 add(E e) 和 set(E e) 方法)。
            3. 获取当前位置:ListIterator 提供了 nextIndex() 和 previousIndex() 方法来获取当前迭代位置的索引。
            4. 检查可迭代方向:hasNext() 和 hasPrevious() 方法用来检查迭代器是否有下一个或上一个元素。
            • ListIterator 的基本操作:
              • add(E e): 在 next() 或 previous() 调用之后,可以在列表中的当前位置插入一个元素。
              • hasNext(): 如果迭代器有更多元素进行正向遍历,则返回 true。
              • next(): 返回迭代器中的下一个元素并前进。
              • hasPrevious(): 如果迭代器有更多元素进行反向遍历,则返回 true。
              • previous(): 返回迭代器中的上一个元素并后退。
              • set(E e): 用指定的元素替换最后一次由 next() 或 previous() 返回的元素。
              • nextIndex(): 返回下一个调用 next() 方法时返回的元素的索引。
              • previousIndex(): 返回下一个调用 previous() 方法时返回的元素的索引。

                增强for

                1. 基本使用

                  • 作用:遍历集合或者数组
                  • 格式:

                    for(元素类型 变量名:要遍历的集合名或者数组名){

                    变量名就是代表的每一个元素

                    }

                  • 快捷键:集合名或者数组名.for
                    import java.util.ArrayList;
                    public class LinkList {
                        public static void main(String[] args) {
                            ArrayList s = new ArrayList<>();
                            s.add("a");
                            s.add("b");
                            s.add("c");
                            for (String st : s) {
                                System.out.println(st);
                            }
                            int[] a = {1,2,3,4,5};
                            for(int i : a){
                                System.out.println(i);
                            }
                        }
                    }
                    
                  • 注意

                    1.增强for遍历集合时,底层实现原理为迭代器
                    2.增强for遍历数组时,底层实现原理为普通for
                    

                    所以不管是用迭代器还是使用增强for,在遍历集合的过程中都不要随意修改集合长度,否则会出现并发修改异常

                双列集合

                HashMap

                HashMap的介绍和使用

                1. 概述:HashMap是Map的实现类

                2. 特点:

                  key唯一,value可重复 -> 如果key重复了,会发生value覆盖

                  无序

                  无索引

                  线程不安全

                  可以存null键null值

                3. 数据结构:哈希表

                4. 常用方法:

                  V put(K key, V value) -> 添加元素,返回的是被覆盖的value
                  V remove(Object key) -> 根据key删除键值对,返回的是被删除的value
                  V get(Object key) -> 根据key获取value
                  boolean containsKey(Object key) -> 判断集合中是否包含指定的key
                  判断集合中是否包含指定的value
                          boolean v5 = map.containsValue("d");
                  Collection values() -> 获取集合中所有的value,转存到Collection集合中
                  

                LinkedHashMap

                1. 概述:LinkedHashMap extends HashMap
                2. 特点:

                  key唯一,value可重复 -> 如果key重复了,会发生value覆盖

                  有序

                  无索引

                  线程不安全

                  可以存null键null值

                3. 数据结构:哈希表 + 双向链表
                4. 使用:和HashMap一样

                HashMap的两种遍历方式

                1. 获取key,根据key再获取value

                  Set KeySet() -> 将Map中的Key获取出来,转存到Set集合中
                  
                  import java.util.LinkedHashMap;
                  import java.util.Set;
                  public class HashMap1 {
                      public static void main(String[] args) {
                          LinkedHashMap map = new LinkedHashMap<>();
                          map.put("a", "b");
                          map.put("c", "d");
                          Set keySet = map.keySet();
                          for (String key : keySet) {
                              String value = map.get(key);
                              System.out.println(key + "=" + value);
                          }
                      }
                  }
                  
                2. 同时获取key和value

                  Set> entrySet() -> 获取Map集合中的键值对,转存到Set集合中
                  
                  import java.util.*;
                  public class HashMap1 {
                      public static void main(String[] args) {
                          LinkedHashMap map = new LinkedHashMap<>();
                          map.put("a", "b");
                          map.put("c", "d");
                          map.put("k", "l");
                          Set> entries = map.entrySet();
                          for (Map.Entry entry : entries) {
                              System.out.println(entry.getKey() + " = " + entry.getValue());
                          }
                      }
                  }
                  

                Map存储自定义对象时如何去重复

                import java.util.Objects;
                public class Person {
                    private String name;
                    private int age;
                    public Person(String name, int age) {
                        this.name = name;
                        this.age = age;
                    }
                    public String getName() {
                        return name;
                    }
                    public int getAge() {
                        return age;
                    }
                    public void setName(String name) {
                        this.name = name;
                    }
                    public void setAge(int age) {
                        this.age = age;
                    }
                    @Override
                    public String toString() {
                        return "Person [name=" + name + ", age=" + age + "]";
                    }
                    @Override
                    public boolean equals(Object o) {
                        if (this == o) return true;
                        if (o == null || getClass() != o.getClass()) return false;
                        Person person = (Person) o;
                        return age == person.age && Objects.equals(name, person.name);
                    }
                    @Override
                    public int hashCode() {
                        return Objects.hash(name, age);
                    }
                }
                import java.util.HashMap;
                public class PersonText {
                    public static void main(String[] args) {
                        HashMap map = new HashMap<>();
                        map.put(new Person("哈哈",18),"渭南");
                        map.put(new Person("天天",16),"西安");
                        map.put(new Person("解决",15),"重庆");
                        map.put(new Person("哈哈",18),"北京");
                        System.out.println(map);
                    }
                }
                

                如果key为自定义类型,去重复的话,重写hashCode和equals方法,去重复过程和set一样,因为set集合的元素到了底层都是保存到了map和key位置上

                TreeMap

                1. 概述:TreeMap是Map的实现类
                2. 特点:

                  对key进行排序

                  无索引

                  不能存null

                  线程不安全

                  key唯一

                3. 数据结构:红黑树
                TreeMap() -> 使用其键的自然顺序构造一个新的空树图。
                TreeMap(Comparator comparator) -> 构造一个新的空树图,根据给定的比较器排序。
                    
                import java.util.Comparator;
                import java.util.TreeMap;
                public class PersonText {
                    public static void main(String[] args) {
                        TreeMap map = new TreeMap(new Comparator() {
                            @Override
                            public int compare(Person o1, Person o2) {
                                return o1.getAge()-(o2.getAge());
                            }
                        });
                        map.put(new Person("hh",16),"a");
                        map.put(new Person("jj",19),"k");
                        map.put(new Person("gg",12),"c");
                        System.out.println(map);
                        //[Person{name=gg, age=12}, Person{name=hh, age=16}, Person{name=jj, age=19}]
                    }
                }
                

                Hashtable集合

                1. 概述:Hashtable是Map的实现类

                2. 特点:

                  key唯一,value可重复 -> 如果key重复了,会发生value覆盖

                  无序

                  无索引

                  线程不安全

                  不可以存null键null值

                3. 数据结构:哈希表

                import java.util.Hashtable;
                public class HashTable {
                    public static void main(String[] args) {
                        Hashtable ht = new Hashtable();
                        ht.put("a", "b");
                        ht.put("c", "d");
                        ht.put("e", "f");
                        ht.put("c", "h");
                       // ht.put(null,null);//报错
                        System.out.println(ht); //{a=b, e=f, c=h}
                    }
                }
                

                HashMap和Hashtable区别:

                • 相同点:元素无序、无索引、key唯一

                • 不同点:HashMap线程不安全,Hashtable线程安全

                  ​ HashMap可以存储null键null值,Hashtable不可以

                  Properties集合

                  1. 概述:Properties继承Hashtable

                  2. 特点:

                    key唯一,value可重复 -> 如果key重复了,会发生value覆盖

                    无序

                    无索引

                    线程不安全

                    不可以存null键null值

                    Properties的key与value默认为String

                  3. 数据结构:哈希表

                  4. 常用方法:

                    Object setProperty(String key, String value) -> 存键值对
                    String getProperty(String key) -> 根据key获取value
                    Set stringPropertyNames() -> 获取所有的key,保存到set集合中,相当于keySet方法
                    void load(InputStream inStream) -> 从输入字节流中读取属性列表(键和元素对)
                    
                    无序
                    无索引
                    线程不安全
                    不可以存null键null值
                    
                  5. 数据结构:哈希表

                  import java.util.Hashtable;
                  public class HashTable {
                      public static void main(String[] args) {
                          Hashtable ht = new Hashtable();
                          ht.put("a", "b");
                          ht.put("c", "d");
                          ht.put("e", "f");
                          ht.put("c", "h");
                         // ht.put(null,null);//报错
                          System.out.println(ht); //{a=b, e=f, c=h}
                      }
                  }
                  

                  HashMap和Hashtable区别:

                  • 相同点:元素无序、无索引、key唯一

                  • 不同点:HashMap线程不安全,Hashtable线程安全

                    ​ HashMap可以存储null键null值,Hashtable不可以

                    Properties集合

                    1. 概述:Properties继承Hashtable

                    2. 特点:

                      key唯一,value可重复 -> 如果key重复了,会发生value覆盖

                      无序

                      无索引

                      线程不安全

                      不可以存null键null值

                      Properties的key与value默认为String

                    3. 数据结构:哈希表

                    4. 常用方法:

                      Object setProperty(String key, String value) -> 存键值对
                      String getProperty(String key) -> 根据key获取value
                      Set stringPropertyNames() -> 获取所有的key,保存到set集合中,相当于keySet方法
                      void load(InputStream inStream) -> 从输入字节流中读取属性列表(键和元素对)
                      

                    总结

                    1. List接口:
                    • ArrayList:基于动态数组实现,适用于随机访问。插入和删除元素时可能需要数组复制,因此较慢。
                    • LinkedList:基于双向链表实现,适用于频繁的插入和删除操作。但是,随机访问速度较慢。
                    • Vector:类似于ArrayList,但它是同步的。由于性能问题,通常不推荐使用。
                    • 选择:当需要频繁随机访问元素时,选择ArrayList。当需要频繁在列表中间插入或删除元素时,选择LinkedList。
                      1. Set接口:
                      • HashSet:基于HashMap实现,无序,允许null元素,查找速度快。
                      • LinkedHashSet:类似于HashSet,但维护元素的插入顺序。
                      • TreeSet:基于NavigableMap实现,可以按照自然顺序或自定义顺序对元素进行排序。
                      • 选择:当需要快速查找元素且不需要元素有序时,选择HashSet。当需要维护元素插入顺序时,选择LinkedHashSet。当需要有序集合时,选择TreeSet。
                        1. Map接口:
                        • HashMap:基于散列表实现,键值对映射,无序,允许一个null键和多个null值。
                        • LinkedHashMap:类似于HashMap,但维护键值对的插入顺序。
                        • TreeMap:基于红黑树实现,可以按照自然顺序或自定义顺序对键进行排序。
                        • Hashtable:类似于HashMap,但它是同步的。由于性能问题,通常不推荐使用。
                        • 选择:当需要快速查找键值对且不需要键有序时,选择HashMap。当需要维护键值对的插入顺序时,选择LinkedHashMap。当需要有序的键值对映射时,选择TreeMap。

转载请注明来自码农世界,本文标题:《Java集合》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,70人围观)参与讨论

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

Top