Java集合框架

集合

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

和数组的区别

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

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

位置:java.util.*

Collection体系集合

Collection接口

练习一

复制代码
 package com.collection.demo01;
 ​
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 ​
 /*
  * Collection接口的使用
  * 1.添加元素
  * 2.删除元素
  * 3.遍历元素
  * 4.判断
  * */
 public class Demo01 {
     public static void main(String[] args) {
         //创建集合
         Collection collection = new ArrayList();
         //添加元素 add()
         collection.add("苹果");
         collection.add("西瓜");
         collection.add("榴莲");
         System.out.println("元素个数:" + collection.size());
         System.out.println(collection); //相当于sout(collection.toString());
         //删除元素 remove()
 //        collection.remove("榴莲");
 //        System.out.println("删除后"+collection.size());
 //        collection.clear();
 //        System.out.println("清除后"+collection.size());
 ​
         //遍历元素
         //1.使用增强for forEach 普通for不能用,因为没有下标
         for (Object o : collection) {
             System.out.println(o);
         }
         //2.使用迭代器 Iterator 专门用来遍历集合的一种方式
         Iterator it = collection.iterator();    //Iterator遍历collection的迭代器 hasNext():有没有下一个元素 next():获取下一个元素 remove():删除当前元素
         while (it.hasNext()) {
             String s = (String) it.next();
             System.out.println(s);
             //collection.remove(s);   //迭代时不能进行集合删除操作 会报异常:ConcurrentModificationException
             //it.remove();    //使用迭代器的remove方法是可以的
 ​
         }
         System.out.println("元素个数" + collection.size());
 ​
         //判断 contains() isEmpty()
         System.out.println(collection.contains("西瓜"));
         System.out.println(collection.isEmpty());   //判断元素是否为空
 ​
 ​
     }
 }
 ​

练习二

复制代码
 package com.collection.demo01;
 ​
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
 ​
 //Collection的使用:保存学生信息
 public class Demo02 {
     public static void main(String[] args) {
         //新建一个Collection对象
         Collection collection = new ArrayList();
         //创建学生对象
         Student s1 = new Student("Tom",1);
         Student s2 = new Student("Jack",2);
         Student s3 = new Student("Jack",3);
         //1.添加学生数据
         collection.add(s1);
         collection.add(s2);
         collection.add(s3);
         collection.add(s3);
         System.out.println("元素个数" + collection.size());
         System.out.println(collection.toString());
         //删除
         collection.remove(s3);  //只是把地址删除,堆里还留着
         System.out.println("删除之后" + collection.size());
 ​
         //1.增强for
         for(Object o : collection) {
             Student s = (Student)o;
             System.out.println(s);
         }
 ​
         //2.迭代器
         Iterator iterator = collection.iterator();
         while(iterator.hasNext()) {
             Student s = (Student)iterator.next();
             System.out.println(s);
         }
         //判断
         System.out.println(collection.contains(new Student("Tom",1)));  //false 并不是原有的Tom
         System.out.println(collection.contains(s1));
         System.out.println(collection.isEmpty());
 ​
     }
 ​
 }
 ​
复制代码
 package com.collection.demo01;
 ​
 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 "名字:"  + name +
                 ", 年龄:" + age +
                 "\t";
     }
 }
 ​

List集合

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

List方法使用

案例1:

复制代码
 package com.collection.demo02;
 ​
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
 ​
 /*
 * List接口的使用
 * 1.有序、有下标
 * 2.可重复
 ​
 * */
 public class Demo01 {
     public static void main(String[] args) {
         //创建集合对象
         List list = new ArrayList();
         //1.添加元素
         list.add("iPhone");
         list.add("xiaomi");
         list.add(0,"HUAWEI");   //表示在角标为0位置添加
         System.out.println("元素个数"+list.size());
         System.out.println(list);
         //删除元素
         list.remove(0); //把第一个元素删除
         System.out.println("元素个数"+list.size());
         System.out.println(list);
 ​
         //遍历
         //1.for
         for (int i = 0; i < list.size(); i++) {
             System.out.println(list.get(i));
         }
         //2.forEach
         for(Object o : list) {
             System.out.println(o);
         }
         //3.迭代器
         Iterator iterator = list.iterator();
         while (iterator.hasNext()) {
             System.out.println(iterator.next());
         }
         //4.列表迭代器
         /*
         * 和Iterator的区别:
         * ListIterator可以向前向后遍历,可以增、删、改元素
         * */
         //4.1从前往后
         ListIterator lit = list.listIterator();
         while (lit.hasNext()) {
             System.out.println(lit.nextIndex()+ ":" +lit.next());
         }
         //4.2从后往前
         while (lit.hasPrevious()) {
             System.out.println(lit.previousIndex()+ ":" +lit.previous());
         }
 ​
         //判断
         System.out.println(list.contains("xiaomi"));
         System.out.println(list.isEmpty());
 ​
         //获取位置
         System.out.println(list.indexOf("xiaomi"));
 ​
     }
 }
 ​

案例2:

复制代码
 package com.collection.demo02;
 ​
 ​
 import java.util.ArrayList;
 import java.util.List;
 ​
 /*
 * List的使用
 *
 * */
 public class demo02 {
     public static void main(String[] args) {
         //创建集合
         List list = new ArrayList();
         //添加数字数据(隐含自动装箱) 集合不能存储基本类型数据
         list.add(20);
         list.add(30);
         list.add(40);
         list.add(50);
         list.add(60);
         System.out.println("元素个数"+list.size());
         System.out.println(list);
         //删除
         //list.remove(20);    //默认删除角标是20的元素
         //System.out.println("删除数据后"+list.size());    //报错:IndexOutOfBoundsException
         //解决方法
 //        list.remove(0);
 //        list.remove((Object)20);
 //        list.remove(new Integer(20));
 ​
         //补充方法subList 截取集合 返回子集合
         List subList = list.subList(1, 3); //含头不含尾
         System.out.println(subList);
 ​
     }
 }
 ​

List实现类

ArrayList
  • ArrayList【重点】:

    • 数组结构实现,内部有数组,查询快、增删满

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

    源码分析:

    默认容量DEFAULT_CAPACITY = 10

    注意:如果没有向集合中添加任何元素时,容量0,添加任意一个元素,容量为10,超过10,扩容,每次扩容大小是原来的1.5倍

    存放元素数组:elementData

    size 实际元素个数

    add()

复制代码
 package com.collection.demo02;
 ​
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.ListIterator;
 ​
 /*
 * ArrayList的使用
 * 存储结构:查找遍历速度快,增删慢
 *
 * */
 public class Demo03 {
     public static void main(String[] args) {
         ArrayList arrayList = new ArrayList<>();
         //添加元素
         Student s1 = new Student("Tom",1);
         Student s2 = new Student("Jack",2);
         Student s3 = new Student("Jerry",3);
         arrayList.add(s1);
         arrayList.add(s2);
         arrayList.add(s3);
         System.out.println("元素个数"+arrayList.size());
         System.out.println(arrayList);
         //删除元素
 //        arrayList.remove(s1);
 //        System.out.println("删除之后"+arrayList.size());
 //        System.out.println(arrayList);
 //        arrayList.remove(new Student("Tom",1)); //remove其实调用了equals(this == obj)方法
         //想要实现这行代码,解决方案:重写equals
 ​
        //遍历元素【重点】
         //1.for
         for (int i = 0; i < arrayList.size(); i++) {
             System.out.println(arrayList.get(i));
         }
         //2.forEach
         for(Object o: arrayList) {
             System.out.println(o);
         }
         //迭代器
         Iterator it = arrayList.iterator();
         while(it.hasNext()) {
             Student s = (Student)it.next();
             System.out.println(s);
         }
         //列表迭代器
         //正序
         ListIterator lit = arrayList.listIterator();
         while(lit.hasNext()){
             Student s = (Student)lit.next();
             System.out.println(s);
         }
         //倒序
         while(lit.hasPrevious()){
             Student s = (Student)lit.previous();
             System.out.println(s);
         }
 ​
         //判断
         System.out.println(arrayList.contains(s1));
         System.out.println(arrayList.contains(new Student("Tom",1)));
         System.out.println(arrayList.isEmpty());
 ​
         //查找
         System.out.println(arrayList.indexOf(s1));
         System.out.println(arrayList.indexOf(new Student("Tom",1)));
 ​
     }
 }
 ​
Vector
  • Vector:

    • 数组结构实现,查询快、增删慢

    • 1.0版本,运行效率满,线程安全

复制代码
 package com.collection.demo02;
 ​
 import java.util.Enumeration;
 import java.util.Vector;
 ​
 public class Demo04 {
     public static void main(String[] args) {
         //创建集合
         Vector vector = new Vector();
         //添加元素
         vector.add("草莓");
         vector.add("西瓜");
         vector.add("苹果");
         System.out.println(vector);
         //删除元素
 //        vector.remove(1);
 //        vector.remove("苹果");
 //        System.out.println(vector);
         //遍历元素
         //1.for
         for(int i = 0; i < vector.size();i++){
             System.out.println(vector.get(i));
         }
         //2.foreach
         for (Object o : vector) {
             System.out.println(o);
         }
         //3.使用枚举器
         Enumeration enumeration = vector.elements();
         while(enumeration.hasMoreElements()) {
             System.out.println(enumeration.nextElement());
         }
 ​
         //4.判断
         System.out.println(vector.contains("草莓"));
         System.out.println(vector.isEmpty());
 ​
         //5.其他方法:firstElement,lastElement,elementAt
     }
 }
 ​
LinkedList
  • LinkedList:

    • 链表结构实现,双向链表,增删快,查询慢
复制代码
 package com.collection.demo02;
 ​
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.ListIterator;
 ​
 public class Demo05 {
     public static void main(String[] args) {
         //创建集合
         LinkedList list = new LinkedList();
 ​
         Student s1 = new Student("Tom",1);
         Student s2 = new Student("Tom",2);
         Student s3 = new Student("Tom",3);
 ​
         //添加元素
         list.add(s1);
         list.add(s2);
         list.add(s3);
 ​
         //删除元素
 //        list.remove(s1);
 //        list.remove(1);
 //        list.clear();
 ​
         //遍历元素
        //1.for
         for(int i = 0; i < list.size(); i++) {
             System.out.println(list.get(i));
         }
         //2.forEach
         for (Object o : list) {
             System.out.println(o);
         }
         //3.迭代器
         Iterator it = list.iterator();
         while(it.hasNext()) {
             System.out.println(it.next());
         }
 ​
         //4.使用列表迭代器
         //正序
         ListIterator lit = list.listIterator();
         while(lit.hasNext()) {
             System.out.println(lit.next());
         }
 ​
         //倒序
         while(lit.hasPrevious()) {
             System.out.println(lit.previous());
         }
 ​
         //判断
         System.out.println(list.contains(s1));
         System.out.println(list.isEmpty());
 ​
         //查找
         System.out.println(list.indexOf(s2));
     }
 }
 ​
ArrayList和LinkedList区别

ArrayList:必须开辟连续空间,查询快,增删慢

LinkedList:无需开辟连续空间,查询慢,增删快

泛型

泛型类

复制代码
package com.collection.generic;
/*
* 泛型类
* 语法:类名<T>
* T是类型占位符,表示一种引用类型,如果编写多个用","隔开
*
*
* */
public class MyGeneric<T> {
    //使用泛型
    //1.创建变量
    T t;
    //2.添加方法 泛型作为方法的参数
    public void show(T t) {
        //不能实例化 new T()
        System.out.println(t);
    }

    //3.泛型作为方法的返回值
    public T getT() {
        return t;
    }

}
复制代码
package com.collection.generic;

public class TestGeneric {
    public static void main(String[] args) {
        //使用泛型类创建对象 占位符T只能是引用类型
        MyGeneric<String> myGeneric = new MyGeneric<>();    //后面的<>里可写可不写 1.7之前一定要写

        myGeneric.t = "hello";
        myGeneric.show("Welcome");
       String s = myGeneric.getT();

       MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
       myGeneric2.t = 100;
       myGeneric2.show(200);
       Integer i = myGeneric2.getT();

       //不同泛型类型对象之间不能相互赋值
        //MyGeneric<String> myGeneric3 = myGeneric2;
        MyGeneric<String> myGeneric3 = myGeneric;
        myGeneric3.show("都是String泛型,就可以直接赋值");

    }
}

泛型接口

复制代码
package com.collection.generic;

public class MyInterfaceImpl implements MyInterface<String> {
    @Override
    public String server(String s) {
        System.out.println(s);
        return s;
    }
}
复制代码
package com.collection.generic;
//接口的实现类也不确定类型,就将实现类变成泛型 实现类是什么类型 接口就也是这个类型
public class MyInterfaceImpl2<T> implements MyInterface<T> {
    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}
复制代码
package com.collection.generic;

public class Test1 {
    public static void main(String[] args) {
        MyInterfaceImpl impl = new MyInterfaceImpl();
        String str = impl.server("接口实现类重写的方法");
        System.out.println(str);

        MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
        impl2.server(100);

    }
}

泛型方法

复制代码
package com.collection.generic;
/*
* 泛型方法
* 语法:<T> 方法的返回值类型
* */
public class MyGenericMethod {

        //泛型方法
        public <T> void show(T t) {
            System.out.println("MyGenericsMethod:"+t.getClass().getName());
        }
        
}
复制代码
package com.collection.generic;

public class Test2 {
    public static void main(String[] args) {
        //泛型方法
        MyGenericMethod myGenericMethod = new MyGenericMethod();
        myGenericMethod.show("Welcome");    //T的类型跟你在这行传递的数据而确定
        myGenericMethod.show(200);
        myGenericMethod.show(3.14);

    }
}

泛型好处

  • 提高代码的重用性,没学泛型之前要方法的重载才能用同一个方法输出不同类型的对象

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

泛型集合

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

  • 特点:

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

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

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

复制代码
package com.collection.generic;

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 boolean equals(Object obj) {
        if(this == obj){
            return true;
        }
        if(obj == null){
            return false;
        }
        if(obj instanceof Student){
            Student s = (Student)obj;
            if(s.getName().equals(this.name)&&s.getAge() == this.age){
                return true;
            }
        }
        return false;
    }

    @Override
    public String toString() {
        return "名字:"  + name +
                ", 年龄:" + age +
                "\t";
    }
}
复制代码
 package com.collection.generic;
 ​
 import java.util.ArrayList;
 import java.util.Iterator;
 ​
 public class Demo {
     public static void main(String[] args) {
         ArrayList<String> list = new ArrayList<>();
         list.add("A");
         list.add("B");
         list.add("C");
 ​
         for (String s : list) {
             System.out.println(s);
         }
 ​
         ArrayList<Student> list1 = new ArrayList<>();
         Student s1 = new Student("Tom", 1);
         Student s2 = new Student("Jack", 2);
         Student s3 = new Student("Jane", 3);
         list1.add(s1);
         list1.add(s2);
         list1.add(s3);
 ​
        Iterator<Student> iterator = list1.iterator();
        while (iterator.hasNext()) {
            Student student = iterator.next();
            System.out.println(student);
        }
     }
 }

set集合

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

  • 方法:全部继承Collection方法

复制代码
 package com.collection.demo04;
 ​
 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<String>();
 ​
         //1.添加数据
         set.add("iPhone");
         set.add("iPad");
         set.add("Mac");
         set.add("Mac"); //没有添加进来,和上面的重复了
         System.out.println("元素个数"+set.size());
 ​
         //2.删除数据
 //        set.remove("iPhone");   //不能通过角标删除
 //        System.out.println("删除后元素个数"+set.size());
 //        set.clear();
 //        System.out.println("清除后元素个数"+set.size());
 ​
         //3.遍历【重点】
         //3.1 增强for
         for (String s : set) {
             System.out.println(s);
         }
         //3.2 迭代器
         Iterator<String> iterator = set.iterator();
         while (iterator.hasNext()) {
             System.out.println(iterator.next());
         }
         //4.判断
         System.out.println(set.contains("iPhone"));
         System.out.println(set.isEmpty());
     }
 }
 ​

Set实现类

HashSet【重点】
  • 基于HashCode计算元素存放位置

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

案例1:

复制代码
 package com.collection.demo04;
 ​
 import java.util.HashSet;
 import java.util.Iterator;
 ​
 /*
 * HashSet集合的使用
 * 存储结构:哈希表(数组+链表+红黑树(1.8引入))
 *
 * */
 public class Demo02 {
     public static void main(String[] args) {
         //创建集合
         HashSet<String> hashSet = new HashSet<String>();
         //添加元素
         hashSet.add("米法");
         hashSet.add("力巴尔");
         hashSet.add("乌尔波扎");
         hashSet.add("达尔克尔");
         hashSet.add("达尔克尔");    //重复的添加不进去
         System.out.println("英杰个数" + hashSet.size());
 ​
         //删除数据
 //        hashSet.remove("米法");
 //        hashSet.clear();
 //        System.out.println("英杰个数"+hashSet.size());
 ​
         //3.遍历
         //3.1 增强for
         for (String s : hashSet) {
             System.out.println(s);
         }
         //3.2 使用迭代器
         Iterator<String> iterator = hashSet.iterator();
         while (iterator.hasNext()) {
             System.out.println(iterator.next());
         }
         //4.判断
         System.out.println(hashSet.contains("林克"));
         hashSet.clear();
         System.out.println(hashSet.isEmpty());
 ​
     }
 }
 ​

案例2:

复制代码
 package com.collection.demo04;
 ​
 import com.collection.demo02.Student;
 ​
 public class Person {
     private String name;
     private int age;
 ​
     public Person() {
     }
 ​
     public Person(String name, int age) {
         this.name = name;
         this.age = age;
     }
 ​
     public int getAge() {
         return age;
     }
 ​
     public void setAge(int age) {
         this.age = age;
     }
 ​
     public String getName() {
         return name;
     }
 ​
     public void setName(String name) {
         this.name = name;
     }
 ​
     @Override
     public String toString() {
         //重写toString方法不然默认打印哈希值
         return "名字:"+name+";年龄:"+age;
     }
 ​
     @Override
     public int hashCode() {
         int n1 = this.name.hashCode();
         int n2 = this.age;
         return n1 + n2;
     }
 ​
     @Override
     public boolean equals(Object obj) {
         if(this == obj){
             return true;
         }
         if(obj == null){
             return false;
         }
         if(obj instanceof Person){
             Person p = (Person)obj;
             if(p.getName().equals(this.name)&&p.getAge() == this.age){
                 return true;
             }
         }
         return false;
 ​
     }
 }
 ​
复制代码
 package com.collection.demo04;
 ​
 import java.util.HashSet;
 import java.util.Iterator;
 ​
 public class Demo03 {
     public static void main(String[] args) {
         //创建对象
         HashSet<Person> person = new HashSet<>();
         //1.添加对象
         Person p1 = new Person("Tom", 1);
         Person p2 = new Person("Jack", 2);
         Person p3 = new Person("Jane", 3);
 ​
         person.add(p1);
         person.add(p2);
         person.add(p3);
         person.add(p3); //重复的不能添加
         person.add(new Person("Tom", 1));   //这样会添加进去 想让它p1是重复的 就重写hashCode() equals()
         /*
         * 存储过程
         * 根据hashCode计算保存的位置
         * 位置为空:保存
         * 位置不为空->
         * 执行equals方法
         * 如果equals方法为true:认为重复
         * false:形成链表
         * */
         System.out.println("元素个数" + person.size());
 ​
         //删除元素
         person.remove(p1);
         System.out.println("元素个数" + person.size());
 ​
         //遍历
         //1.增强for
         for (Person person1 : person) {
             System.out.println(person1);
         }
 ​
         //2.迭代器
         Iterator<Person> iterator = person.iterator();
         while (iterator.hasNext()) {
             System.out.println(iterator.next());
         }
         //判断
         System.out.println(person.contains(p1));
         System.out.println(person.contains(new Person("Jack", 2))); //true 因为重写了hashCode equals
 ​
     }
 }
 ​

HashSet补充

以前系统重写的hashCode()出现31:

  • 31是一个质数,可以生成均匀的数据,减少散列冲突

  • 提升执行效率 31*i = (i << 5) - i;位运算快

TreeSet
  • 基于排列顺序实现元素不重复 二叉查找树

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

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

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

案例1:

复制代码
 package com.collection.demo04;
 ​
 import java.util.Iterator;
 import java.util.TreeSet;
 ​
 /*
  *TreeSet的使用
  *存储结构:红黑树
  * */
 public class Demo04 {
     public static void main(String[] args) {
         //创建集合
         TreeSet<String> treeSet = new TreeSet<String>();
         //1.添加元素
         treeSet.add("xyz");
         treeSet.add("abc");
         treeSet.add("Hello");
         treeSet.add("xyz"); //重复的添加不来
 ​
         System.out.println("元素个数" + treeSet.size());
 ​
         //2.删除
         treeSet.remove("xyz");
         System.out.println("删除后元素个数" + treeSet.size());
 ​
         //3.遍历
         //3.1增强for
         for (String s : treeSet) {
             System.out.println(s);
         }
         //3.2迭代器
         Iterator<String> iterator = treeSet.iterator();
         while (iterator.hasNext()) {
             System.out.println(iterator.next());
         }
         //4.判断
         System.out.println(treeSet.contains("abc"));
 ​
     }
 }
 ​

案例2:

复制代码
 package com.collection.demo04;
 ​
 import com.collection.demo02.Student;
 ​
 public class Person implements Comparable<Person> {
     private String name;
     private int age;
 ​
     public Person() {
     }
 ​
     public Person(String name, int age) {
         this.name = name;
         this.age = age;
     }
 ​
     public int getAge() {
         return age;
     }
 ​
     public void setAge(int age) {
         this.age = age;
     }
 ​
     public String getName() {
         return name;
     }
 ​
     public void setName(String name) {
         this.name = name;
     }
 ​
     @Override
     public String toString() {
         //重写toString方法不然默认打印哈希值
         return "名字:"+name+";年龄:"+age;
     }
 ​
     @Override
     public int hashCode() {
         int n1 = this.name.hashCode();
         int n2 = this.age;
         return n1 + n2;
     }
 ​
     @Override
     public boolean equals(Object obj) {
         if(this == obj){
             return true;
         }
         if(obj == null){
             return false;
         }
         if(obj instanceof Person){
             Person p = (Person)obj;
             if(p.getName().equals(this.name)&&p.getAge() == this.age){
                 return true;
             }
         }
         return false;
 ​
     }
 ​
     //先按姓名比,再按年龄比
     @Override
     public int compareTo(Person o) {
         int n1 = this.getName().compareTo(o.getName());
         int n2 = this.getAge() - o.getAge();
         return n1 == 0 ? n2: n1;
 ​
     }
 }
 ​
复制代码
 package com.collection.demo04;
 ​
 import java.util.Iterator;
 import java.util.TreeSet;
 ​
 /*
 * 使用TreeSet保存数据
 * 存储结构:红黑树
 *要求:元素必须要实现Comparable接口,重写compareTo方法,compareTo返回值0,认为重复
 * */
 public class Demo05 {
     public static void main(String[] args) {
         //创建集合
         TreeSet<Person> treeSet = new TreeSet<Person>();
         //添加元素
         Person p1 = new Person("Tom", 1);
         Person p2 = new Person("Jack", 1);
         Person p3 = new Person("Jane", 1);
 ​
         treeSet.add(p1);
         treeSet.add(p2);
         treeSet.add(p3);
         treeSet.add(new Person("Jack", 2));
         System.out.println("元素个数" + treeSet.size());
         System.out.println(treeSet);
         //报错:Person cannot be cast to java.lang.Comparable
         //二叉查找树放元素是小在左、大在右,我们并没有对Person类进行说明怎么比,就报错
 ​
         //删除
 //        treeSet.remove(p1);
 //        System.out.println(treeSet.size());
 //        treeSet.remove(new Person("Jack", 1));  //这样也能删除
 ​
 ​
         //遍历
         //增强for
         for (Person person : treeSet) {
             System.out.println(person);
         }
         //迭代器
         Iterator<Person> iterator = treeSet.iterator();
         while (iterator.hasNext()) {
             System.out.println(iterator.next());
         }
 ​
         //判断
         System.out.println(treeSet.contains(new Person("Tom", 1))); //true
     }
 }
Comparator接口
复制代码
 package com.collection.demo04;
 ​
 import java.util.Comparator;
 import java.util.TreeSet;
 ​
 /*
 * TreeSet的使用
 * Comparator:实现定制比较(比较器)
 * Comparable:可比较的
 * */
 public class Demo06 {
     public static void main(String[] args) {
         //创建集合
         TreeSet<Person> persons = new TreeSet<>(new Comparator<Person>(){
             //Comparator是一个接口不能直接new来实例化,这里我们使用匿名内部类
             @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("Tom", 1);
         Person p2 = new Person("Jack", 2);
         Person p3 = new Person("Jane", 3);
         persons.add(p1);
         persons.add(p2);
         persons.add(p3);
         System.out.println(persons);
 ​
     }
 }
 ​

案例:

复制代码
 package com.collection.demo04;
 ​
 import java.util.Comparator;
 import java.util.TreeSet;
 ​
 /*
 * 要求:使用TreeSet集合实现字符串长度进行排序
 * Comparator接口进行定制比较
 * */
 public class Demo07 {
     public static void main(String[] args) {
         //创建集合,并指定规则
         TreeSet<String> set = new TreeSet<String>(new Comparator<String>() {
             @Override
             public int compare(String o1, String o2) {
                 int n1 = o1.length() - o2.length();
                 int n2 = o1.compareTo(o2);
                 return n1 == 0 ? n2:n1;
             }
         });
         //添加数据
         set.add("a");
         set.add("z");
         set.add("ab");
         set.add("bbc");
         set.add("abc");
         set.add("b");
         System.out.println(set);
 ​
     }
 }
 ​

Map体系集合

Map接口的特点:

  1. 用于存储任意键值对(Key-Value)

  2. 键:无序、无下标、不允许重复

  3. 值:无序、无下标、允许重复

复制代码
 package com.collection.map;
 ​
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 ​
 /*
 * Map接口的使用
 * 特点:存储键值对 键不能重复值可以重复 无序
 *
 * */
 public class Demo01 {
     public static void main(String[] args) {
         //创建集合
         Map<String, String> map = new HashMap<>();
         //1.添加元素
         map.put("cn","中国");
         map.put("uk","英国");
         map.put("usa","美国");
         map.put("cn","China");
 ​
         System.out.println("元素个数"+map.size());  //还是3个
         System.out.println(map);    //打印出来发现,cn的value是China,把中国替换了
 ​
         //2/删除
 //        map.remove("usa");  //通过key来删除
 //        System.out.println("删除后"+map.size());
 ​
         //3.遍历
         //3.1使用keySet()
         Set<String> keySet = map.keySet();  //变成Set集合
         for (String key : keySet) { //可以和上一行合并for(String key: map.keySet())
             System.out.println(key+":"+map.get(key));   //通过key获得value
         }
         //3.2使用entrySet方法 效率高于keySet()
         map.entrySet();
         Set<Map.Entry<String, String>> entrySet = map.entrySet();
         for (Map.Entry<String, String> entry : entrySet) {  //同样可以和上一行合并for(Map.Entry<String,String> entry : Map.entrySet())
             System.out.println(entry.getKey()+":"+entry.getValue());
         }
         //4.判断
         System.out.println(map.containsKey("cn"));
         System.out.println(map.containsValue("北京"));
 ​
     }
 }
 ​

Map实现类

HashMap 【重点】

和HashSet的关系,HashSet用的就是HashMap,add调用了put

线程不安全,运行效率快允许null作为key或者value

复制代码
 package com.collection.map;
 ​
 import java.util.HashMap;
 import java.util.Map;
 ​
 /*
 * HashMap集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 使用key的hashCode和equals作为依据判断重复
 * */
 public class Demo02 {
     public static void main(String[] args) {
         //创建集合
         HashMap<Student, String> students = new HashMap<Student, String>();
         //1.添加元素
         Student s1 = new Student("孙悟空", 1);
         Student s2 = new Student("猪八戒",2);
         Student s3 = new Student("沙和尚", 3);
         students.put(s1,"花果山");
         students.put(s2,"高老庄");
         students.put(s3,"河");
         students.put(s3,"流沙河");   //不能加进来,key不能重复 ,但是会把之前value替换
         students.put(new Student("沙和尚", 3),"取经路上"); //可以加进来,new的和s3在堆里面地址不同 除非重写hashCode 和 equals, 可以alt+insert直接生成重写的这里不赘述
         System.out.println("元素个数"+students.size());
         System.out.println(students);
 ​
         //2.删除
        students.remove(s1); //通过key删除
         //3.遍历
         //3.1 keySet
         for(Student key : students.keySet()) {
             System.out.println(key+" "+students.get(key));
         }
         //3.2 entrySet
         for(Map.Entry<Student, String> entry : students.entrySet()) {
             System.out.println(entry.getKey()+" "+entry.getValue());
         }
         //判断
         System.out.println(students.containsKey(s1));
         System.out.println(students.containsKey(new Student("猪八戒", 2)));    //没重写hashCode equals 堆里面还没有这个 false 如果重写了和s2一样,true
         System.out.println(students.containsValue("花果山"));
     }
 }
 ​

HashMap源码总结

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

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

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

  • jdk1.8 当链表长度小于6时,调整成链表

  • jdk1.8 以前,链表头插入,1.8以后,尾插入

Hashtable和Properties

线程安全,运行效率慢,不允许null作为key或者是value

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

TreeMap

和TreeSet的关系,TreeSet用的就是TreeMap,add调用了put

实现了SortedMap接口,可以对key自动排序

复制代码
 package com.collection.map;
 ​
 import java.util.Map;
 import java.util.TreeMap;
 ​
 /*
 * TreeMap的使用
 * 存储结构:红黑树
 *
 * */
 public class Demo03 {
     public static void main(String[] args) {
         //创建集合
         TreeMap<Student, String> students = new TreeMap<Student, String>();
         //添加元素
         Student s1 = new Student("孙悟空", 1);
         Student s2 = new Student("猪八戒",2);
         Student s3 = new Student("沙和尚", 3);
         students.put(s1,"花果山");
         students.put(s2,"高老庄");
         students.put(s3,"流沙河");
         students.put(new Student("沙和尚", 3),"取经路上"); //不能加进来,但是把value替换了
         System.out.println("元素个数"+students.size());
         System.out.println(students);   //出现类型转换异常 Student cannot be cast to java.lang.Comparable 去Student类里实现Comparable接口并创建比较规则
 ​
         //2.删除
 //        students.remove(s1);
 //        students.remove(new Student("猪八戒", 2)); //能删除,把他当作s2
 //        System.out.println(students.size());
 ​
         //3.遍历
         //3.1使用keySet
         for (Student key: students.keySet()) {
             System.out.println(key+":"+students.get(key));
         }
         //3.2使用entrySet
        for(Map.Entry<Student, String> entry: students.entrySet()) {
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
        //4.判断
         System.out.println(students.containsKey(new Student("猪八戒", 2)));    //true
 ​
     }
 }
 ​

Collections工具类

复制代码
 package com.collection.demo05;
 ​
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 ​
 /*
 * Collections工具类的使用
 *
 * */
 public class Demo01 {
     public static void main(String[] args) {
         List<Integer> list = new ArrayList<Integer>();
         list.add(38);
         list.add(134);
         list.add(4);
         list.add(115);
         list.add(35);
         System.out.println("排序前"+list);
 ​
         //sort排序
         Collections.sort(list);
         System.out.println("排序后"+list);
 ​
         //binarySearch 二分查找
         int i = Collections.binarySearch(list, 38);// 返回2,第三个元素
         int j = Collections.binarySearch(list, 0);// 返回负数 表示不存在
         System.out.println(i +" "+j);
 ​
         //copy 复制
 //        List<Integer> dest= new ArrayList<>();
 //        Collections.copy(dest, list);
 //        System.out.println(dest);   //异常:下标越界 copy方法要求两个集合大小相同
         //解决方式
         List<Integer> dest = new ArrayList<>();
         for(int k = 0; k < list.size(); k++) {
             dest.add(0);
         }        //给dest的元素和list一样多且都初始化为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 转成 数组
         Integer[] arr = list.toArray(new Integer[list.size()]);
         //new Integer[a]  a<list.size()就自动把 a = list.size(), a > list.size() a多的就是null null...
         System.out.println(arr.length);
         System.out.println(Arrays.toString(arr));
         //数组转成list 转后的集合是受限集合,不能对集合的元素进行修改
         String[] names = {"Tom","Jerry","Jack","Mike","Bob"};
         List<String> list2 = Arrays.asList(names);
         System.out.println(list2);
 ​
         //把基本类型数组转成集合,需要修改为包装类
         int[] nums = {1,2,3,4,5};
         List<int[]> list3 = Arrays.asList(nums);    //不好,用下面的
         System.out.println(list3);
 ​
         Integer[] num = {1,2,3,4,5};
         List<Integer> list4 = Arrays.asList(num);
         System.out.println(list4);
 ​
     }
 }
相关推荐
全栈凯哥20 分钟前
Java详解LeetCode 热题 100(17):LeetCode 41. 缺失的第一个正数(First Missing Positive)详解
java·算法·leetcode
神经毒素25 分钟前
WEB安全--Java安全--LazyMap_CC1利用链
java·开发语言·网络·安全·web安全
逸夕28 分钟前
httpclient请求出现403
java
帅帅哥的兜兜31 分钟前
next.js实现项目搭建
前端·react.js·next.js
筱歌儿36 分钟前
css 左右布局
前端·css
酷炫码神1 小时前
C#语法基础
开发语言·c#
ddd...e_bug1 小时前
GMT之Bash语言使用
开发语言·bash
码农秋1 小时前
填坑记: 古董项目Apache POI 依赖异常排除
开发语言·tomcat·jsp·poi·依赖冲突
qq_653644461 小时前
如何查看打开的 git bash 窗口是否是管理员权限打开
开发语言·windows·git·bash
sadoshi1 小时前
phpstudy的Apache添加AddType application/x-httpd-php .php .php5配置无效的处理方式
开发语言·php·apache