Java集合详解

Java集合详解,

学习视频-千锋教育Java集合框架详解:视频链接

HashMap视频详解:视频链接

Java集合详解

集合的概念

什么是集合

  • 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能

  • 和数组的区别:

    1. 数组长度固定,集合长度不固定

    2. 数组可以存储基本类型和引用类型,集合只能存储引用类型

  • 位置:java.util;

Collection接口

Collection接口

  • 特点:代表一组任意类型的对象,部分有序、部分有下表、部分能重复

  • 方法:

    • boolean add(Object obj) //添加一个对象

    • boolean addAll(Collection c) //将一个集合中的所有对象添加到此集合中

    • void clear() //清空此集合中的所有对象

    • boolean contains(Object obj) //检查此集合中是否包含o对象

    • boolean equals(Object obj) //比较此集合是否与指定对象相等

    • boolean isEmpty() //判断此集合是否为空

    • boolean remove(Object o) //在此集合中移除o对象

    • int size() //返回此集合中的元素个数

    • Object[] toArray() //将此集合转换成数组

    • package com.tang.collection;
      
      import java.util.ArrayList;
      import java.util.Collection;
      import java.util.Iterator;
      
      /**
       * Collection接口的使用
       * 0.清空元素
       * 1.添加元素
       * 2.删除元素
       * 3.遍历元素
       * 4.判断
       */
      public class CollectionDemo01 {
          public static void main(String[] args) {
              //创建集合
              Collection collection = new ArrayList();
              // 0.清空元素
              collection.clear();
              // 1.添加元素
              collection.add("苹果");
              collection.add("西瓜");
              collection.add("香蕉");
              System.out.println("元素个数:"+collection.size());
              System.out.println(collection);
              // 2.删除元素
              collection.remove("苹果");
              System.out.println("元素个数:"+collection.size());
              // 3.遍历元素【重点】
              //3.1使用增强for循环
              System.out.println("----------3.1使用增强for循环----------");
              for (Object o : collection) {
                  System.out.println(o);
              }
              //3.2使用迭代器(迭代器专门用来遍历集合的一种方式)
              System.out.println("----------3.2使用迭代器----------");
              //hasNext();有没有下一个元素
              //next();获取下一个元素
              //remove()删除当前元素
              Iterator it = collection.iterator();
              while(it.hasNext()){
                  String s = (String) it.next();
                  System.out.println(s);
                  //不能使用方法collection.remove()删除元素
                  //it.remove();
              }
              System.out.println("元素个数:"+collection.size());
              // 4.判断
              //判断元素是否存在
              System.out.println(collection.contains("西瓜"));
              //判断集合是否为空
              System.out.println(collection.isEmpty());
          }
      }
      
    • package com.tang.collection;
      
      //学生类
      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 +
                      '}';
          }
      }
      ---------------------------------------
      package com.tang.collection;
      
      import java.util.ArrayList;
      import java.util.Collection;
      import java.util.Iterator;
      
      /**
       * Collection的使用: 保存学生的信息
       */
      public class CollectionDemo02 {
          public static void main(String[] args) {
              //新建Collection集合
              Collection collection = new ArrayList();
              Student s1 = new Student("糖果", 18);
              Student s2 = new Student("思雨", 18);
              Student s3 = new Student("淑敏", 18);
              //1.添加
              collection.add(s1);
              collection.add(s2);
              collection.add(s3);
              System.out.println(collection);
              //2.删除
              collection.remove(s1);
              System.out.println(collection);
              //3.遍历
              //3.1增强for
              System.out.println("----------3.1增强for----------");
              for (Object s : collection) {
                  System.out.println(s);
              }
              //3.2迭代器:
              // hasNext();next();remove();
              // 迭代过程中不能使用collection的删除方法
              System.out.println("----------3.2迭代器----------");
              Iterator it = collection.iterator();
              while (it.hasNext()){
                  Student s = (Student) it.next();
                  System.out.println(s);
              }
              // 4.判断
              //判断元素是否存在
              System.out.println(collection.contains(s2));
              //判断集合是否为空
              System.out.println(collection.isEmpty());
          }
      }
      

Iterator迭代器

迭代器:专门用来遍历集合的一种方式

  • hasNext();有没有下一个元素

  • next();获取下一个元素

  • remove()删除当前元素

List接口与实现类

List子接口

  • 特点:有序、有下标、元素可重复

  • 方法:

    • void add(int index, Object o) //在index位置插入对象o

    • boolean addAll(int index, Collection c) //将一个集合中的元素添加到此集合中的index位置

    • Object get(int index) //返回集合中指定位置的元素

    • List subList(int fromIndex, int toIndex) //返回fromIndex和toIndex之间的集合元素

    • package com.tang.list;
      
      import java.util.ArrayList;
      import java.util.Iterator;
      import java.util.List;
      import java.util.ListIterator;
      
      /**
       * List子接口的使用
       * 特点: 有序 有下标 可以重复
       */
      public class ListDemo01 {
          public static void main(String[] args) {
              //创建集合对象
              List list = new ArrayList();
              //1添加元素
              list.add("苹果");
              list.add("小米");
              list.add(0,"华为");
              System.out.println(list);
              //2删除元素
              list.remove(0);
              System.out.println(list);
              //3遍历
              //3.1使用for遍历
              System.out.println("------------3.1使用for遍历------------");
              for (int i = 0; i < list.size(); i++) {
                  System.out.println(list.get(i));
              }
              //3.2使用增强for
              System.out.println("------------3.2使用增强for------------");
              for (Object o : list) {
                  System.out.println(o);
              }
              //3.3使用迭代器
              System.out.println("------------3.3使用迭代器------------");
              Iterator it = list.iterator();
              while (it.hasNext()){
                  System.out.println(it.next());
              }
              //3.4使用列表迭代器,和Iterator的区别:
              // ListIterator可以向前或向后遍历,添加、删除、修改元素
              ListIterator lit = list.listIterator();
              System.out.println("------------3.4使用列表迭代器-从前往后------------");
              while (lit.hasNext()){
                  System.out.println(lit.nextIndex()+": "+lit.next());
              }
              System.out.println("------------3.4使用列表迭代器-从后往前------------");
              while (lit.hasPrevious()){
                  System.out.println(lit.previousIndex()+": "+lit.previous());
              }
              //4判断
              //判断元素是否存在
              System.out.println(list.contains("苹果"));
              //判断集合是否为空
              System.out.println(list.isEmpty());
              //5获取元素位置(首次出现的位置)
              System.out.println(list.indexOf("小米"));
          }
      
      }
      
    • package com.tang.list;
      
      import java.util.ArrayList;
      import java.util.List;
      
      /**
       * List的使用
       */
      public class ListDemo02 {
          public static void main(String[] args) {
              //创建集合对象
              List list = new ArrayList();
              //1添加数字数据(自动装箱)
              list.add(20);
              list.add(30);
              list.add(40);
              list.add(50);
              list.add(60);
              System.out.println(list);
              //2删除
              list.remove(0);
              // list.remove((Object)20);
              // list.remove((Integer)20);
              // list.remove(new Integer(20));
              // list.remove(Integer.valueOf(20));
              System.out.println(list);
              //3补充方法subList: 返回子集合, 含头不含尾[1,3)
              List subList = list.subList(1, 3);
              System.out.println(subList);
          }
      }
      

List实现类

ArrayList【重点】:
  • 数字结构实现,查询快,增删慢

  • JDK1.2版本,运行效率快、线程不安全

  • 源码分析:

    • DEFAULT_CAPACITY = 10; 默认容量

      • 注意:

        • 没有向集合中添加任何元素时,容量是0;

        • 每次扩容大小是原来的1.5倍

    • elementData:存放元素的数组

    • size:实际的元素个数

    package com.tang.list;
    
    import com.tang.collection.Student;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.ListIterator;
    
    /**
     * ArrayList的使用
     * 存储结构:数组,遍历速度快,增删慢
     */
    public class ArrayListDemo01 {
        public static void main(String[] args) {
            //创建集合
            ArrayList arrayList = new ArrayList();
            //1添加元素
            Student s1 = new Student("甜甜", 18);
            Student s2 = new Student("思雨", 18);
            Student s3 = new Student("淑敏", 18);
            arrayList.add(s1);
            arrayList.add(s2);
            arrayList.add(s3);
            System.out.println("元素个数: "+arrayList.size());
            System.out.println(arrayList);
            //2删除元素
            arrayList.remove(new Student("甜甜", 18));
            System.out.println("元素个数: "+arrayList.size());
            System.out.println(arrayList);
            //3遍历元素【重点】
            //3.1使用迭代器
            System.out.println("----------3.1使用迭代器----------");
            Iterator it = arrayList.iterator();
            while (it.hasNext()){
                System.out.println(it.next());
            }
            //3.2使用列表迭代器
            System.out.println("----------3.2使用列表迭代器----------");
            ListIterator lit = arrayList.listIterator();
            while (lit.hasNext()){
                System.out.println(lit.nextIndex()+": "+lit.next());
            }
            System.out.println("----------3.2使用列表迭代器-逆序----------");
            while (lit.hasPrevious()){
                System.out.println(lit.previousIndex()+": "+lit.previous());
            }
            //4判断
            //判断元素是否存在
            System.out.println(arrayList.contains(new Student("思雨", 18)));
            //判断集合是否为空
            System.out.println(arrayList.isEmpty());
            //5查找元素下标
            System.out.println(arrayList.indexOf(new Student("思雨", 18)));
        }
    }
    
Vector:
  • 数字结构实现,查询快,增删慢

  • JDK1.0版本,运行效率慢、线程安全

    package com.tang.list;
    
    import java.util.*;
    
    /**
     * 演示Vector的使用
     * 存储结构:数组
     */
    public class VectorDemo01 {
        public static void main(String[] args) {
            //创建集合
            Vector vector = new Vector<>();
            //1添加元素
            vector.add("草莓");
            vector.add("香蕉");
            vector.add("芒果");
            vector.add("苹果");
            System.out.println(vector);
            //2删除元素
            vector.remove(0);
            //vector.remove("草莓");
            System.out.println(vector);
            //3遍历
            //使用枚举器
            System.out.println("----------使用枚举器----------");
            Enumeration en = vector.elements();
            while (en.hasMoreElements()){
                System.out.println(en.nextElement());
            }
            //4判断
            //判断元素是否存在
            System.out.println(vector.contains("芒果"));
            //判断集合是否为空
            System.out.println(vector.isEmpty());
            //5 vector其他的方法
            //firstElement()、lastElement()、elementAt();
        }
    }
    
LinkedList:
  • 链表结构实现,增删快,查询慢

  • 源码分析:

    • int size:集合的大小

    • Node first:链表的头节点

    • Node last:链表的尾节点

不同结构实现方式

ArrayList与LinkedList比较

Set接口与实现类

Set子接口

  • 特点:无序、无下标、元素不可重复

  • 方法:全部继承自Collection中的方法

    package com.tang.set;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    /**
     * 测试Set接口的使用
     * 特点: 无序、没有下标;不能重复
     */
    public class Demo01 {
        public static void main(String[] args) {
            //创建集合
            Set<String> set = new HashSet<>();
            //1添加数据
            set.add("苹果");
            set.add("小米");
            set.add("华为");
            System.out.println("数据个数:"+set.size());
            System.out.println(set);
            //2删除数据
            System.out.println(set.remove("小米"));
            System.out.println(set);
            //3遍历【重点】
            //3.1增强for
            System.out.println("--------增强for-------");
            for (String s : set) {
                System.out.println(s);
            }
            //3.2使用迭代器
            System.out.println("--------使用迭代器-------");
            Iterator<String> it = set.iterator();
            while (it.hasNext()){
                String s = it.next();
                System.out.println(s);
            }
            //4.判断
            System.out.println(set.contains("苹果"));
            System.out.println(set.isEmpty());
        }
    
    }
    

Set实现类

HashSet【重点】
  • 基于HashCode实现元素不重复

  • 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入

  • package com.tang.set;
    
    import java.util.HashSet;
    import java.util.Iterator;
    
    /**
     * HashSet集合的使用
     * 存储结构:哈希表(数组+链表+红黑树)
     */
    public class HashSetDemo1 {
        public static void main(String[] args) {
            //新建集合
            HashSet<String> hashSet = new HashSet<>();
            //1添加元素
            hashSet.add("中国");
            hashSet.add("美国");
            hashSet.add("英国");
            hashSet.add("俄罗斯");
            System.out.println(hashSet);
            //2删除
            hashSet.remove("俄罗斯");
            System.out.println(hashSet);
            //3遍历
            //3.1增强for
            System.out.println("----------增强for---------");
            for (String s : hashSet) {
                System.out.println(s);
            }
            //3.2使用迭代器
            System.out.println("----------使用迭代器---------");
            Iterator<String> it = hashSet.iterator();
            while (it.hasNext()){
                String s = it.next();
                System.out.println(s);
            }
            //4判断
            System.out.println(hashSet.contains("中国"));
            System.out.println(hashSet.isEmpty());
        }
    }
    
  • package com.tang.set;
    
    import java.util.Objects;
    
    /**
     * 人类
     */
    public class Person {
        private String name;
        private int age;
    
        public Person() {
        }
    
        public Person(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 "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 && name.equals(person.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name, age);
        }
    }
    -----------------------------------
    package com.tang.set;
    
    import java.util.HashSet;
    import java.util.Iterator;
    
    /**
     * HashSet的使用
     * 存储结构:哈希表(数组+链表+红黑树)
     * 1.根据hashcode计算保存的位置,如果此位置为空直接保存,如果不为空执行第二步
     * 2.再执行equals方法,如果equals方法为true,则认为是重复的,否则,形成链表
     *
     */
    public class HashSetDemo2 {
        public static void main(String[] args) {
            //新建集合
            HashSet<Person> persons = new HashSet<>();
            //1添加数据
            Person p1 = new Person("糖果",18);
            Person p2 = new Person("思雨",18);
            Person p3 = new Person("淑敏",18);
            Person p4 = new Person("妈妈",30);
            persons.add(p1);
            persons.add(p2);
            persons.add(p3);
            persons.add(p4);
            persons.add(new Person("妈妈",30));
            System.out.println(persons);
            //2删除
            //persons.remove(p1);
            persons.remove(new Person("糖果",18));
            System.out.println(persons);
            //3遍历
            //3.1增强for
            System.out.println("----------增强for---------");
            for (Person person : persons) {
                System.out.println(person);
            }
            //3.2迭代器
            System.out.println("----------迭代器---------");
            Iterator<Person> it = persons.iterator();
            while (it.hasNext()){
                System.out.println(it.next());
            }
            //4判断
            System.out.println(persons.contains(new Person("妈妈", 30)));
            System.out.println(persons.isEmpty());
    
        }
    }
    -----------------------------------
    //JDK1.8生成的hashCode()
    @Override
    public int hashCode() {
        //(1)31是质数,减少散列冲突
        //(2)31提高执行效率 31*i=(i<<5)-i 移位操作效率更高
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    
TreeSet:
  • 基于排列顺序实现元素不重复

  • 实现了SortedSet接口,对集合元素自动排序

    • 方式一:

      • 元素对象的类型实现了Comparable接口,指定排序规则

      • 通过CompareTo方法确定是否为重复元素

    • 方式二:

      • Comparator接口实现定制比较
    • 方式一:元素对象的类型实现了Comparable接口

    • package com.tang.set;
      
      import java.util.Iterator;
      import java.util.TreeSet;
      
      /**
       * TreeSet的使用
       * 存储结构:红黑树
       */
      public class TreeSetDemo1 {
          public static void main(String[] args) {
              //1创建集合
              TreeSet<String> treeSet = new TreeSet<>();
              treeSet.add("edf");
              treeSet.add("cde");
              treeSet.add("abc");
              treeSet.add("bcd");
              System.out.println(treeSet);
              //2删除
              treeSet.remove("abc");
              System.out.println(treeSet.size());
              System.out.println(treeSet);
              //3遍历
              //3.1增强for
              System.out.println("---------增强for--------");
              for (String s : treeSet) {
                  System.out.println(s);
              }
              //3.2迭代器
              System.out.println("---------迭代器--------");
              Iterator<String> it = treeSet.iterator();
              while (it.hasNext()){
                  System.out.println(it.next());
              }
              //判断
              System.out.println(treeSet.contains("bcd"));
              System.out.println(treeSet.isEmpty());
          }
      }
      
    • package com.tang.set;
      
      import java.util.Objects;
      
      /**
       * 人类
       */
      public class Person implements Comparable{
          private String name;
          private int age;
      
          public Person() {
          }
      
          public Person(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 "Person{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      
          //先按姓名比,再按年龄比
          @Override
          public int compareTo(Object o) {
              int n1 = this.getName().compareTo(((Person)o).getName());
              int n2 = this.getAge()-((Person)o).getAge();
      
              return n1==0?n2:n1;
          }
      }
      ---------------------------------
      package com.tang.set;
      
      import java.util.Iterator;
      import java.util.TreeSet;
      
      /**
       * TreeSet的使用
       * 存储结构:红黑树
       * 要求:必须实现Comparable接口,compareTo方法返回值为0,认为是重复元素
       */
      public class TreeSetDemo2 {
          public static void main(String[] args) {
              //1创建集合
              TreeSet<Person> persons = new TreeSet<>();
              Person p1 = new Person("糖果",18);
              Person p2 = new Person("思雨",18);
              Person p3 = new Person("淑敏",18);
              Person p5 = new Person("淑敏",19);
              Person p4 = new Person("妈妈",30);
              persons.add(p1);
              persons.add(p2);
              persons.add(p3);
              persons.add(p4);
              persons.add(p5);
              System.out.println(persons.size());
              System.out.println(persons);
              //3删除
              persons.remove(p1);
              //persons.remove(new Person("糖果",18));
              System.out.println(persons.size());
              System.out.println(persons);
              //3遍历
              //3.1增强for
              System.out.println("---------增强for--------");
              for (Person p : persons) {
                  System.out.println(p);
              }
              //3.2迭代器
              System.out.println("---------迭代器--------");
              Iterator<Person> it = persons.iterator();
              while (it.hasNext()){
                  System.out.println(it.next());
              }
              //4判断
              System.out.println(persons.contains(p2));
              System.out.println(persons.contains(new Person("思雨",18)));
              System.out.println(persons.isEmpty());
          }
      }
      
    • 方式二:Comparator接口实现定制比较

    • package com.tang.set;
      
      import java.util.Comparator;
      import java.util.Iterator;
      import java.util.TreeSet;
      
      /**
       * TreeSet的使用
       * 存储结构:红黑树
       * 要求:Comparator接口实现定制比较,compare方法返回值为0,认为是重复元素
       */
      public class TreeSetDemo3 {
          public static void main(String[] args) {
              //1创建集合,并指定比较规则
              TreeSet<Person> persons = new TreeSet<>(new Comparator<Person>() {
                  @Override
                  public int compare(Person o1, Person o2) {
                      int n1 = o1.getAge()-o2.getAge();
                      int n2 = o1.getName().compareTo(o2.getName());
                      return n1==0?n2:n1;
                  }
              });
              Person p1 = new Person("糖果",19);
              Person p2 = new Person("思雨",16);
              Person p3 = new Person("淑敏",16);
              Person p4 = new Person("妈妈",31);
              Person p5 = new Person("淑敏",17);
              Person p6 = new Person("糖果",16);
              persons.add(p1);
              persons.add(p2);
              persons.add(p3);
              persons.add(p4);
              persons.add(p5);
              persons.add(p6);
              System.out.println(persons.size());
              System.out.println(persons);
              //2删除
              persons.remove(p4);
              //persons.remove(new Person("糖果",18));
              System.out.println(persons.size());
              System.out.println(persons);
              //3遍历
              //3.1增强for
              System.out.println("---------增强for--------");
              for (Person p : persons) {
                  System.out.println(p);
              }
              //3.2迭代器
              System.out.println("---------迭代器--------");
              Iterator<Person> it = persons.iterator();
              while (it.hasNext()){
                  System.out.println(it.next());
              }
              //4判断
              System.out.println(persons.contains(p2));
              System.out.println(persons.contains(new Person("思雨",16)));
              System.out.println(persons.isEmpty());
          }
      }
      
    • package com.tang.set;
      
      import java.util.Comparator;
      import java.util.TreeSet;
      
      /**
       * 要求:使用TreeSet集合实现字符串按照长度进行排序
       * Comparator接口实现定制比较
       */
      public class TreeSetDemo4 {
          public static void main(String[] args) {
              //创建集合,并指定比较规则
              TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
                  @Override
                  public int compare(String o1, String o2) {
                      int n1 = o1.compareTo(o2);
                      int n2 = o1.length()-o2.length();
                      return n2==0?n1:n2;
                  }
              });
              treeSet.add("lang");
              treeSet.add("糖果");
              treeSet.add("fight");
              treeSet.add("wight");
              treeSet.add("无花果");
              System.out.println(treeSet.size());
              System.out.println(treeSet);
          }
      }
      

Map接口与实现类

Map集合

Map集合

Map父接口

  • 特点:存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复

  • 方法:

    • V put(K key, V value) //将对象存入到集合中。关联键值。key重复则覆盖原值

    • Object get(Object key) //根据键获取对应的值

    • Set //返回所有key

    • Collection values() //返回包含所有值的Collection集合

    • Set<Map.Entry<K, V>> //键值匹配的Set集合

    • entrySet()效率高于keySet()

      package com.tang.Map;
      
      import java.util.HashMap;
      import java.util.Map;
      
      /**
       * Map接口的使用
       * 特点:(1)存储键值对(2)键不能重复,值可以重复(3)无序、无下标
       */
      public class MapDemo1 {
          public static void main(String[] args) {
              //创建Map集合
              Map<String, String> map = new HashMap<>();
              //1添加元素
              map.put("cn", "中国");
              map.put("uk", "英国");
              map.put("usa", "美国");
              System.out.println(map.size());
              System.out.println(map);
              //2删除
              map.remove("usa");
              System.out.println(map.size());
              System.out.println(map);
              //3遍历
              //3.1使用keySet()方法,获取key(键)的集合
              System.out.println("-------使用keySet()-------");
              //Set<String> keySet = map.keySet();
              for (String key : map.keySet()) {
                  System.out.println(key+"="+map.get(key));
              }
              //3.2使用entrySet()方法,获取entry(键值对)的集合
              System.out.println("-------使用entrySet()-------");
              //Set<Map.Entry<String, String>> entries = map.entrySet();
              for (Map.Entry<String, String> entry : map.entrySet()) {
                  System.out.println(entry);
                  System.out.println(entry.getKey()+"--"+entry.getValue());
              }
              //4判断
              System.out.println(map.containsKey("cn"));
              System.out.println(map.containsValue("英国"));
              System.out.println(map.isEmpty());
          }
      }
      

Map集合的实现类

HashMap【重点】

  • JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value

  • 容量必须是2的n次方,源码:因为取模运算h%r=(r-1)&&h;

    HashMap图解

    红黑树

  • 问题:

    • 多线程会出现数据丢失的问题

    • JDK1.7及之前采用头插法:会形成循环链表

    • 链表循环

  • 源码总结:

    1. HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16

    2. 当元素的个数大于(容量*0.75)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数

    3. JDK1.8当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的提高执行效率

    4. JDK1.8当链表长度小于6时,调整成链表

    5. JDK1.8之前链表是头插入,JDK1.8之后是尾插入

  • package com.tang.Map;
    
    import java.util.Objects;
    
    /**
     * 学生类
     */
    public class Student {
        private String name;
        private int id;
    
        public Student() {
        }
    
        public Student(String name, int age) {
            this.name = name;
            this.id = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return id;
        }
    
        public void setAge(int age) {
            this.id = age;
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "name='" + name + '\'' +
                    ", age=" + id +
                    '}';
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            Student student = (Student) o;
            return id == student.id && Objects.equals(name, student.name);
        }
    
        @Override
        public int hashCode() {
            return Objects.hash(name, id);
        }
    }
    -------------------------
    package com.tang.Map;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     *HashMap集合的使用
     * 存储结构:哈希表(数组+链表+红黑树)
     * 使用key的hashcode和equals作为重复
     */
    public class HashMapDemo1 {
        public static void main(String[] args) {
            //创建集合
            HashMap<Student,String> students = new HashMap<>();
            //刚创建hashmap没有添加元素时table=null  size=0目的节省空间
            //添加元素
            Student s1 = new Student("糖果", 1001);
            Student s2 = new Student("思雨", 1002);
            Student s3 = new Student("淑敏", 1003);
            students.put(s1,"上海");
            students.put(s2,"北京");
            students.put(s3,"河南");
            students.put(new Student("淑敏", 1003),"河南");
            System.out.println("元素个数: "+students.size());
            System.out.println(students);
            //2删除
            System.out.println("删除: "+students.remove(s1));
            System.out.println("元素个数: "+students.size());
            System.out.println(students);
            //3遍历
            //3.1使用keySet()方法
            System.out.println("-------使用keySet()-------");
            for (Student student : students.keySet()) {
                System.out.println(student + "=" + students.get(student));
            }
            //3.1使用entrySet()方法
            System.out.println("-------使用entrySet()-------");
            for (Map.Entry<Student, String> entry : students.entrySet()) {
                System.out.println(entry);
            }
            //4判断
            System.out.println(students.containsKey(new Student("思雨", 1002)));
            System.out.println(students.containsValue("河南"));
            System.out.println(students.isEmpty());
        }
    }
    

Hashtable

  • JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value

  • Properties:

    • Hashtable的子类,要求key和value都是String。通常用于配置文件的读取

TreeMap

  • 实现了SortedMap接口(是Map的子接口),对key自动排序

  • 基于排列顺序实现key不重复

    • 方式一:

      • key的类型实现了Comparable接口,指定排序规则

      • 通过CompareTo方法确定是否为重复key

    • 方式二:

      • Comparator接口实现定制比较
    • 方式一:key的类型实现了Comparable接口

      package com.tang.Map;
      
      import java.util.Objects;
      
      /**
       * 学生类
       */
      public class Student implements Comparable<Student>{
          private String name;
          private int id;
      
          public Student() {
          }
      
          public Student(String name, int age) {
              this.name = name;
              this.id = age;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public int getId() {
              return id;
          }
      
          public void setId(int id) {
              this.id = id;
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "name='" + name + '\'' +
                      ", age=" + id +
                      '}';
          }
      
          //按学号比
          @Override
          public int compareTo(Student o) {
              return this.id-o.getId();
          }
      }
      ---------------------------------------
      package com.tang.Map;
      
      import java.util.Comparator;
      import java.util.Map;
      import java.util.TreeMap;
      
      /**
       * TreeMap集合的使用
       * 存储结构:红黑树
       * 方式一:必须实现Comparable接口,compareTo方法返回值为0,认为是重复元素
       */
      public class TreeMapDemo1 {
          public static void main(String[] args) {
              //创建集合
              TreeMap<Student,String> treeMap = new TreeMap<>();
              //添加元素
              Student s1 = new Student("糖果", 1001);
              Student s2 = new Student("思雨", 1002);
              Student s3 = new Student("淑敏", 1003);
              treeMap.put(s1,"上海");
              treeMap.put(s2,"北京");
              treeMap.put(s3,"河南");
              treeMap.put(new Student("淑敏", 1003),"上海");
              System.out.println("元素个数: "+treeMap.size());
              System.out.println(treeMap);
              //2删除
              System.out.println("删除: "+treeMap.remove(s1));
              System.out.println("元素个数: "+treeMap.size());
              System.out.println(treeMap);
              //3遍历
              //3.1使用keySet()方法
              System.out.println("-------使用keySet()-------");
              for (Student student : treeMap.keySet()) {
                  System.out.println(student + "=" + treeMap.get(student));
              }
              //3.1使用entrySet()方法
              System.out.println("-------使用entrySet()-------");
              for (Map.Entry<Student, String> entry : treeMap.entrySet()) {
                  System.out.println(entry);
              }
              //4判断
              System.out.println(treeMap.containsKey(new Student("思雨", 1002)));
              System.out.println(treeMap.containsValue("河南"));
              System.out.println(treeMap.isEmpty());
          }
      }
      
    • 方式二:Comparator接口实现定制比较

      package com.tang.Map;
      
      import java.util.Comparator;
      import java.util.Map;
      import java.util.TreeMap;
      
      /**
       * TreeMap集合的使用
       * 存储结构:红黑树
       * 方式二:Comparator接口实现定制比较,compare方法返回值为0,认为是重复元素
       */
      public class TreeMapDemo1 {
          public static void main(String[] args) {
              //创建集合(定制比较)
              TreeMap<Student,String> treeMap = new TreeMap<>(new Comparator<Student>() {
                  @Override
                  public int compare(Student o1, Student o2) {
                      return o1.getId()-o2.getId();
                  }
              });
              //添加元素
              Student s1 = new Student("糖果", 1001);
              Student s2 = new Student("思雨", 1002);
              Student s3 = new Student("淑敏", 1003);
              treeMap.put(s1,"上海");
              treeMap.put(s2,"北京");
              treeMap.put(s3,"河南");
              treeMap.put(new Student("淑敏", 1003),"上海");
              System.out.println("元素个数: "+treeMap.size());
              System.out.println(treeMap);
              //2删除
              System.out.println("删除: "+treeMap.remove(s1));
              System.out.println("元素个数: "+treeMap.size());
              System.out.println(treeMap);
              //3遍历
              //3.1使用keySet()方法
              System.out.println("-------使用keySet()-------");
              for (Student student : treeMap.keySet()) {
                  System.out.println(student + "=" + treeMap.get(student));
              }
              //3.1使用entrySet()方法
              System.out.println("-------使用entrySet()-------");
              for (Map.Entry<Student, String> entry : treeMap.entrySet()) {
                  System.out.println(entry);
              }
              //4判断
              System.out.println(treeMap.containsKey(new Student("思雨", 1002)));
              System.out.println(treeMap.containsValue("河南"));
              System.out.println(treeMap.isEmpty());
          }
      }
      

Collections工具类

  • 概念:集合工具类,定义了除了存取以外的集合常用方法

  • 方法:

    • public static void reverse(List<?> list) //反转集合中元素的顺序

    • public static void shuffle(List<?> list) //随机重置集合元素的顺序

    • public static <T extends Comparable<? super T>> void sort(List list) //升序排序(元素类型必须实现Comparable接口)

      package com.tang.collections;
      
      import java.util.ArrayList;
      import java.util.Arrays;
      import java.util.Collections;
      import java.util.List;
      
      /**
       *演示Collections工具类的使用
       */
      public class Demo1 {
          public static void main(String[] args) {
              List<Integer> list = new ArrayList<>();
              list.add(20);
              list.add(4);
              list.add(30);
              list.add(8);
              list.add(15);
              // sort排序
              System.out.println("排序之前: "+list);
              Collections.sort(list);
              System.out.println("排序之后: "+list);
              // binarySearch二分查找
              int i = Collections.binarySearch(list, 15);
              System.out.println(i);
              // copy复制,两个的集合的长度需要相等
              List<Integer> dest = new ArrayList<>();
              for (int j = 0; j < list.size(); j++) {
                  dest.add(0);
              }
              Collections.copy(dest, list);
              System.out.println(dest);
              //reverse反转
              Collections.reverse(list);
              System.out.println("反转之后: "+list);
              //shuffle打乱
              Collections.shuffle(list);
              System.out.println("打乱之后: "+list);
              //list集合转数组
              System.out.println("--------list集合转数组---------");
              Integer[] array = list.toArray(new Integer[0]);
              System.out.println(array.length);
              System.out.println(Arrays.toString(array));
              //数组转list集合
              System.out.println("--------数组转list集合---------");
              String[] names = {"tg","sy","sm","mm","bb","gg"};
              //集合是一个受限集合,不能添加和删除
              List<String> list2 = Arrays.asList(names);
              System.out.println(list2);
              //把基本类型数组转成集合时,需要改为包装类型
              Integer[] nums = {1,2,3,4,5};
              List<Integer> list3 = Arrays.asList(nums);
              System.out.println(list3);
          }
      }
      

泛型

泛型

  • Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参考传递

  • 常见形式有泛型类、泛型接口、泛型方法

  • 语法:

    • <T,...> T称为类型占位符,表示一种引用类型
  • 好处:

    1. 提高代码的重用性

    2. 防止类型转换异常,提高代码的安全性

    •   package com.tang.generic;
        
        /**
         * 泛型类
         * 语法: 类名<T>
         * T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
         */
        public class MyGeneric<T> {
            //使用泛型T
            //1创建变量
            T t;
            //2创建方法,泛型作为方法的参数
            public void show(T t){
                System.out.println(t);
            }
            //3创建方法,泛型作为方法的返回值
            public T getT(){
                return t;
            }
        }
        ---------------------------------
        package com.tang.generic;
        
        //测试类
        public class TestGeneric {
            public static void main(String[] args) {
                //使用泛型类型创建对象
                //注意:1泛型只能使用引用类型,2不同泛型类型之间不能相互赋值
                MyGeneric<String> myGeneric = new MyGeneric<>();
                myGeneric.t="hello";
                myGeneric.show("大家好");
                String s = myGeneric.getT();
                System.out.println(s);
        		//使用泛型类型创建对象
                MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
                myGeneric2.t = 100;
                myGeneric2.show(200);
                Integer i = myGeneric2.getT();
                System.out.println(i);
            }
        }
      
    •   package com.tang.generic;
        
        /**
         * 泛型接口
         * 语法: 接口名<T>
         * 注意: 不能泛型静态常量
         */
        public interface MyInterface<T> {
            String name = "张三";
            T server(T t);
        }
        ---------------------
        package com.tang.generic;
        
        /**
         * 泛型接口
         * 语法: 接口名<T>
         * 注意: 不能泛型静态常量
         */
        public class MyInterfaceImpl implements MyInterface<String>{
        
            @Override
            public String server(String s) {
                System.out.println(s);
                return s;
            }
        }
        -------------------------
        package com.tang.generic;
        
        /**
         * 泛型接口
         * 语法: 接口名<T>
         * 注意: 不能泛型静态常量
         */
        public class MyInterfaceImpl2<T> implements MyInterface<T>{
            @Override
            public T server(T t) {
                System.out.println(t);
                return t;
            }
        }
        -------------------------
        package com.tang.generic;
        
        //测试类
        public class TestGeneric {
            public static void main(String[] args) {
        		//泛型接口的实现类1创建对象
                MyInterfaceImpl impl = new MyInterfaceImpl();
                impl.server("泛型接口的实现类中的方法");
                //泛型接口的实现类2创建对象
                MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
                impl2.server(300);
            }
        }
      
    • package com.tang.generic;
      
      /**
       * 泛型方法
       * 语法: <T> 返回值类型
       */
      public class MyGenericMethod<T> {
          //泛型方法
          public <T> T show(T t){
              System.out.println("泛型方法: "+t);
              return t;
          }
      }
      --------------------
      package com.tang.generic;
      
      //测试类
      public class TestGeneric {
          public static void main(String[] args) {
              //泛型方法
              MyGenericMethod myGenericMethod = new MyGenericMethod();
              myGenericMethod.show("糖果");
              myGenericMethod.show(100);
              myGenericMethod.show(3.14);
          }
      }
      

泛型集合

  • 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致

  • 特点:

    • 编译时即可检查,而非运行时抛出异常

    • 访问时,不必类型转换(拆箱)

    • 不同泛型之间不能相互赋值,泛型不存在多态

      package com.tang.genericList;
      
      import com.tang.collection.Student;
      
      import java.util.ArrayList;
      import java.util.Iterator;
      
      public class Demo1 {
          public static void main(String[] args) {
              ArrayList<String> arrayList = new ArrayList<>();
              for (String s : arrayList) {
                  System.out.println(s);
              }
              ArrayList<Student> arrayList2 = new ArrayList<>();
              Student s1 = new Student("甜甜", 18);
              Student s2 = new Student("思雨", 18);
              Student s3 = new Student("淑敏", 18);
              arrayList2.add(s1);
              arrayList2.add(s2);
              arrayList2.add(s3);
              //遍历
              Iterator<Student> it = arrayList2.iterator();
              while (it.hasNext()){
                  Student s = it.next();
                  System.out.println(s);
              }
          }
      }
      

集合总结

  • 集合的概念:

    • 对象的容器,和数组类似,定义了对多个对象进行操作的常用方法
  • List集合:

    • 有序、有下标、元素可重复。(ArrayList、LinkedList、Vector)
  • Set集合:

    • 无序、无下标、元素不可重复。(HashSet、TreeSet)
  • Map集合:

    • 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)
  • Collections:

    • 集合工具类,定义了除了存取以外的集合常用方法。
posted @   糖果~  阅读(34)  评论(0编辑  收藏  举报
展开
深色
fff
点击右上角即可分享
微信分享提示