Java进阶_集合

集合

一、集合的概念

1、什么是集合

  • 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
  • 和数组区别:
    • (1)数组长度固定,集合长度不固定
    • (2)数组可以存储基本类型和引用类型,集合只能引用类型
  • 位置: java. util. *;

2、Collection体系集合

3、Collection父接口

Collection接口

  • 特点:代表一组任意类型的对象,无序、无下标、不能重复。、
  • 方法:
    • boolean add(0bject obj) //添加一个对象。
    • boolean addAll (Collection c) //将 一个集合中的所有对象添加到此集合中。
    • void clear() //清空此集合中的所有对象。
    • boolean contains (Object o) //检查此集合中是否包含o对象
    • boolean equals (0bject o) //比较此集合是否与指定对象相等。
    • boolean isEmpty() //判断此集合是否为空
    • boolean remove (Object o) //在 此集合中移除o对象
    • int size() //返回此集合中的元素个数。
    • 0bject[] toArray() //将此集合转换成数组。

二、Collection接口

Collection的使用一:

package com.mike.test;

/*
        collection接口的使用
        (1)添加元素
        (2)删除元素
        (3)遍历元素
        (4)判断
 */


import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;


public class Test {
    public static void main(String[] args){
        //创建集合
        //ArrayList     有序,有下标,可重复
        Collection collection = new ArrayList();
//        (1)添加元素
        collection.add("苹果");
        collection.add("西瓜");
        collection.add("香蕉");
        collection.add("青枣");
        collection.add("鸭梨");
        collection.add("火龙果");
        System.out.println("元素个数:"+collection.size());
        System.out.println(collection);
//        (2)删除元素
        collection.remove("鸭梨");
        System.out.println("-------------------------------");
        System.out.println("元素个数:"+collection.size());
        System.out.println(collection);
//        (3)遍历元素【重点】
        //3.1、使用增强的for(好处是不需要知道下标)
        System.out.println("-----第一种遍历方式,增强for-----");
        for (Object object : collection) {
            System.out.println(object);
        }
        //3.2、使用迭代器(迭代器是专门用来遍历集合的一种方式)
        //迭代过程不能使用集合的删除方法,否则会出现并发修改异常
        System.out.println("-----第二种遍历方式,使用迭代器-----");
        //hasNext();有没有下一个元素,
        //next();获取下一个元素
        //remove();删除当前元素
        Iterator it = collection.iterator();
        while (it.hasNext()){
            String s = (String) it.next();
            System.out.println(s);
        }
//        (4)判断
        System.out.println("----------------------------");
        System.out.println("是否有西瓜:"+collection.contains("西瓜"));
        System.out.println("集合是否为空:"+collection.isEmpty());
    }
}
            /*输出结果
            元素个数:6
            [苹果, 西瓜, 香蕉, 青枣, 鸭梨, 火龙果]
            -------------------------------
            元素个数:5
            [苹果, 西瓜, 香蕉, 青枣, 火龙果]
            -----第一种遍历方式,增强for-----
            苹果
            西瓜
            香蕉
            青枣
            火龙果
            -----第二种遍历方式,使用迭代器-----
            苹果
            西瓜
            香蕉
            青枣
            火龙果
            ----------------------------
            是否有西瓜:true
            集合是否为空:false
            */

Collection的使用二:

集合存对象

Student类

package com.mike.test;

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 + '}';
    }

    @Override
    public boolean equals(Object obj) {
        //1.是不是同一个对象
        if (this==obj){
            return true;
        }
        //2.是不是为空
        if (obj==null){
            return false;
        }
        //3.判断是否是Student类型
        if (obj instanceof Student){
            Student s =(Student) obj;
            //4.比较属性
            if (this.name.equals(s.getName())&&this.age==s.getAge()){
                return true;
            }
        }
        //5.不满足条件,返回false
        return false;
    }
}

Test类

package com.mike.test;

/*
        collection的使用:保存学生信息
        (1)添加元素
        (2)删除元素
        (3)遍历元素
        (4)判断
 */


import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Test {
    public static void main(String[] args){
        //新建Collection对象
        Collection collection = new ArrayList();
        Student student1 = new Student("唐僧", 19);
        Student student2 = new Student("孙悟空", 20);
        Student student3 = new Student("猪八戒", 20);
        Student student4 = new Student("沙僧", 27);
        Student student5 = new Student("白龙马", 21);
        //1、添加学生信息
        collection.add(student1);
        collection.add(student2);
        collection.add(student3);
        collection.add(student4);
        collection.add(student5);
        System.out.println("元素个数"+collection.size());
        System.out.println(collection.toString());
        //2、删除(这里的删除不是删除学生对象,而是删除学生对象在集合中的地址,new的学生对象还在堆当中)
        collection.remove(student1);
        //collection.clear();//清除集合中的元素
        System.out.println("------------------------------");
        System.out.println("删除之后");
        System.out.println("元素个数"+collection.size());
        System.out.println(collection.toString());
        //3、遍历3.1、增强for
        System.out.println("------------------------------");
        System.out.println("遍历元素增强for");
        for (Object object : collection) {
            Student s = (Student) object;
            System.out.println(s.toString());
        }
        //3、遍历3.2、迭代器
        System.out.println("------------------------------");
        System.out.println("遍历元素迭代器");
        Iterator it = collection.iterator();
        while (it.hasNext()){
            Student s = (Student) it.next();
            System.out.println(s.toString());
        }
        //4、判断
        System.out.println("------------------------------");
        System.out.println("判断元素是否存在");
        System.out.println("student1是否存在:"+collection.contains(student1));
        System.out.println("student2是否存在:"+collection.contains(student2));

    }
}
          /*输出结果
            元素个数5
            [Student{name=唐僧, age=19}, Student{name=孙悟空, age=20}, Student{name=猪八			戒, age=20}, Student{name=沙僧, age=27}, Student{name=白龙马, age=21}]
            ------------------------------
            删除之后
            元素个数4
            [Student{name=孙悟空, age=20}, Student{name=猪八戒, age=20}, Student{name=沙			僧, age=27}, Student{name=白龙马, age=21}]
            ------------------------------
            遍历元素增强for
            Student{name=孙悟空, age=20}
            Student{name=猪八戒, age=20}
            Student{name=沙僧, age=27}
            Student{name=白龙马, age=21}
            ------------------------------
            遍历元素迭代器
            Student{name=孙悟空, age=20}
            Student{name=猪八戒, age=20}
            Student{name=沙僧, age=27}
            Student{name=白龙马, age=21}
            ------------------------------
            判断元素是否存在
            student1是否存在:false
            student2是否存在:true
            */

三、List接口与实现类

List接口

  • List子接口

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

    • 方法:

      • void add(int index,0bject o) //在index位置插入对象o。
      • boolean addAll(int index,Collection c) //将一个集合中的元素添加到此集合中的index位置。
      • Object get(int index) //返回集合中指定位置的元素。
      • List subList(int fromIndex,int toIndex) //返回fromIndex和toIndex之间的集合元素。

案例一:

package com.mike.test;

/*
        List子接口的使用
        1、有序,有下标,可以重复
 */


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Test {
    public static void main(String[] args){
        //先创建集合对象
        List list = new ArrayList();
        //1、添加元素
        list.add("苹果");
        list.add("小米");
        list.add("华为");
        list.add(0,"OPPO");
        System.out.println("元素个数:"+list.size());
        System.out.println(list.toString());
        //2、删除元素
        list.remove(0);
        System.out.println("-----------------------------");
        System.out.println("删除之后");
        System.out.println("元素个数:"+list.size());
        System.out.println(list.toString());
        //3、遍历
        //3.1、使用for遍历
        System.out.println("---------使用for遍历--------------");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        //3.2、使用增强for
        System.out.println("-----------使用增强for-------------");
        for (Object object : list) {
            System.out.println(object.toString());
        }
        //3.3、使用迭代器
        System.out.println("-----------使用迭代器-------------");
        Iterator it = list.iterator();
        while (it.hasNext())
            System.out.println(it.next());
        //3.4、使用列表迭代器,, 和Iterator的区别,ListIterator可以向前或向后遍历,添加、删除、修改元素
        System.out.println("-----------使用列表迭代器-------------");
        ListIterator lit = list.listIterator();
        System.out.println("使用列表迭代器,从前往后迭代");
        while (lit.hasNext()) {
            System.out.println(lit.nextIndex()+":"+lit.next());
        }
        System.out.println("使用列表迭代器,从从后往前迭代");
        while (lit.hasPrevious()) {
            System.out.println(lit.previousIndex()+":"+lit.previous());
        }
        //4判断
        System.out.println("==================");
        System.out.println(list.contains("苹果"));
        System.out.println(list.isEmpty());

        //5获取位置
        System.out.println("获取华为下角标:"+list.indexOf("华为"));


    }
}
          /*输出结果
            元素个数:4
            [OPPO, 苹果, 小米, 华为]
            -----------------------------
            删除之后
            元素个数:3
            [苹果, 小米, 华为]
            ---------使用for遍历--------------
            苹果
            小米
            华为
            -----------使用增强for-------------
            苹果
            小米
            华为
            -----------使用迭代器-------------
            苹果
            小米
            华为
            -----------使用列表迭代器-------------
            使用列表迭代器,从前往后迭代
            0:苹果
            1:小米
            2:华为
            使用列表迭代器,从从后往前迭代
            2:华为
            1:小米
            0:苹果
            ==================
            true
            false
            获取华为下角标:2
            */

案例二:

List集合添加基本数据类型(装箱操作)

package com.mike.test;

/*
        List子接口的使用
        1、有序,有下标,可以重复
 */


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Test {
    public static void main(String[] args){
        //先创建集合对象
        List list = new ArrayList();
        //1、添加数字类型(由于集合不能添加基本数据类型,所以这里隐藏了一个步骤,叫装箱)
        //jdk1.5之后,自动装箱
        list.add(10);
        list.add(20);
        list.add(30);
        list.add(40);
        list.add(50);
        System.out.println("元素个数:"+list.size());
        System.out.println(list.toString());
        //2、删除
        //list.remove(0);//删除下标为0的元素
        list.remove(new Integer(20));//由于20是基本数据类型,所以这里必须转换为Integer类型
        System.out.println("元素个数:"+list.size());
        System.out.println(list.toString());

        //3、补充方法subList:()返回子集合,含头不含尾
        List subList = list.subList(1, 3);
        System.out.println(subList.toString());

    }
}
          /*输出结果
            元素个数:5
            [10, 20, 30, 40, 50]
            元素个数:4
            [10, 30, 40, 50]
            [30, 40]
            */

List实现类

  • ArrayList【重点】:

    • 数组结构实现,查询快,增删慢;
    • JDK1. 2版本,运行效率快,线程不安全。
  • Vector:

    • 数组结构实现,查询快,增删慢;
    • JDK1. 0版本,运行效率慢,线程安全。
  • LinkedList:

    • 链表结构实现,增删快,查询慢;

ArrayList的使用

Student类

package com.mike.test;

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 + '}';
    }

    @Override
    public boolean equals(Object obj) {
        //1.是不是同一个对象
        if (this==obj){
            return true;
        }
        //2.是不是为空
        if (obj==null){
            return false;
        }
        //3.判断是否是Student类型
        if (obj instanceof Student){
            Student s =(Student) obj;
            //4.比较属性
            if (this.name.equals(s.getName())&&this.age==s.getAge()){
                return true;
            }
        }
        //5.不满足条件,返回false
        return false;
    }
}

Test类

package com.mike.test;

/*
        ArrayList的使用
        存储结构:数组,查找遍历速度快,增删慢
 */


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class Test {
    public static void main(String[] args){
        //创建集合
        ArrayList arrayList = new ArrayList();
        //1、添加元素
        Student s1 = new Student("刘德华",60);
        Student s2 = new Student("张学友",60);
        Student s3 = new Student("黎明",55);
        Student s4 = new Student("郭富城",56);

        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        arrayList.add(s4);
        arrayList.add(s4);

        System.out.println("元素个数:"+arrayList.size());
        System.out.println(arrayList.toString());
        //2、删除元素
        //如果像下面这样写,我们并不能删除"刘德华",20这个数据,非要这样删除,只能重写equals方法
        //比较创建的对象和集合里面是否为同一个对象,如果数据一样,则认为是同一个对象,允许删除
        //arrayList.remove(new Student("刘德华",20));//equals(this==obj)重写equals方法
        arrayList.remove(4);
        System.out.println("元素个数:"+arrayList.size());
        System.out.println(arrayList.toString());
        //3、遍历元素【重点】
        //3.1、迭代器
        System.out.println("---------迭代器遍历------------");
        Iterator it = arrayList.iterator();
        while (it.hasNext()){
            Student s = (Student) it.next();
            System.out.println(s.toString());
        }
        System.out.println("---------列表迭代器遍历------------");
        ListIterator lit = arrayList.listIterator();
        System.out.println("列表迭代器,从前往后");
        while (lit.hasNext()) {
            Student s = (Student) lit.next();
            System.out.println(lit.previousIndex()+":"+s.toString());//观察最后结果下标
        }
        System.out.println("列表迭代器,从后往前");
        while (lit.hasPrevious()) {
            Student s = (Student) lit.previous();
            System.out.println(lit.previousIndex()+":"+s.toString());//观察最后结果下标
        }
        //4、判断
        //因为这里的Student类重写了equals方法,所以比较的是内容
        System.out.println(arrayList.contains(new Student("郭富城", 56)));
        System.out.println("集合是否为空"+arrayList.isEmpty());
        //5、查找位置(查找下标)
        System.out.println(arrayList.indexOf(s3));
        System.out.println(arrayList.indexOf(s1));
    }
}
          /*输出结果
元素个数:5
[Student{name=刘德华, age=60}, Student{name=张学友, age=60}, Student{name=黎明, age=55}, Student{name=郭富城, age=56}, Student{name=郭富城, age=56}]
元素个数:4
[Student{name=刘德华, age=60}, Student{name=张学友, age=60}, Student{name=黎明, age=55}, Student{name=郭富城, age=56}]
---------迭代器遍历------------
Student{name=刘德华, age=60}
Student{name=张学友, age=60}
Student{name=黎明, age=55}
Student{name=郭富城, age=56}
---------列表迭代器遍历------------
列表迭代器,从前往后
0:Student{name=刘德华, age=60}
1:Student{name=张学友, age=60}
2:Student{name=黎明, age=55}
3:Student{name=郭富城, age=56}
列表迭代器,从后往前
2:Student{name=郭富城, age=56}
1:Student{name=黎明, age=55}
0:Student{name=张学友, age=60}
-1:Student{name=刘德华, age=60}
true
集合是否为空false
2
0
            */

ArrayList源码分析

  • 默认容量大小:DEFAULT_CAPACITY=10;
    • 注意:如果没有向集合中添加任何元素时,容量为0
    • 添加第一个元素之后容量变成10,后面如果需要再次扩容,那么扩容大小是原来的1.5倍
    • 0-->10-->15~~

存放元素的数组:elementData

Vector的使用

向量集合Vector

package com.mike.test;

/*
       Vector的使用
       存储结构:数组,查找遍历速度快,增删慢
 */


import java.util.Enumeration;
import java.util.Vector;

public class Test {
    public static void main(String[] args){
        //1、创建集合,实例化vector
        Vector vector = new Vector();
        //2、添加元素
        vector.add("草莓");
        vector.add("苹果");
        vector.add("西瓜");
        System.out.println("元素个数:"+ vector.size());
        System.out.println(vector.toString());
        //3、删除
//        vector.remove(0);//根据下标移除
//        vector.remove("西瓜");//根据字段移除
//        vector.clear();//将元素从集合中全部移除
        //4、遍历
        //可以使用for,增强for,迭代器,列表迭代器
        //这里我们使用它特有的遍历方式:枚举器(和迭代器功能一模一样,不同名字罢了)
        System.out.println("------枚举器遍历元素------");
        Enumeration en = vector.elements();
        while (en.hasMoreElements()) {
            String o = (String) en.nextElement();
            System.out.println(o);
        }
        //5、判断
        System.out.println("判断是否有西瓜:"+vector.contains("西瓜"));
        System.out.println("判断集合是否为空:"+vector.isEmpty());
        //6、vector其他方法
        //firstElement、lastElement、elementAt()
    }
}
          /*输出结果
                元素个数:3
                [草莓, 苹果, 西瓜]
                ------枚举器遍历元素------
                草莓
                苹果
                西瓜
                判断是否有西瓜:true
                判断集合是否为空:false
            */

LinkedList的使用

package com.mike.test;

/*
       LinkedList的使用
       存储结构:双向链表
       链表结构实现,增删快,查询慢;
 */



import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;

public class Test {
    public static void main(String[] args){
        //1、创建集合,实例化vector
        LinkedList linkedList = new LinkedList();
        //2、添加元素
        Student s1 = new Student("小明",20);
        Student s2 = new Student("小红",18);
        Student s3 = new Student("小军",19);

        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);

        System.out.println("元素个数:"+linkedList.size());
        System.out.println(linkedList.toString());
        //3、删除元素
//         linkedList.remove(s1);
//         linkedList.clear();//清除集合中所有元素
//        System.out.println("删除对象s1之后元素个数:"+ linkedList.size());
//        System.out.println(linkedList.toString());
        //4、遍历
        //4.1使用for遍历
        System.out.println("--------使用for遍历-----------");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
        //4.2使用增强for遍历
        System.out.println("--------使用增强for遍历-----------");
        for (Object o : linkedList) {
            Student s = (Student) o;
            System.out.println(s.toString());
        }
        //4.3使用迭代器遍历
        System.out.println("--------使用迭代器遍历-----------");
        Iterator it = linkedList.iterator();
        while (it.hasNext()) {
            Student s = (Student) it.next();
            System.out.println(s);
        }
        //4.4使用列迭代器
        System.out.println("--------使用列迭代器遍历-----------");
        //从后往前
        ListIterator lit = linkedList.listIterator();
        while (lit.hasNext()) {
            Student s = (Student) lit.next();
            System.out.println(s);
        }
        //5、判断
        System.out.println("判断对象s1是否存在:"+linkedList.contains(s1));
        System.out.println("判断元素是否为空:"+linkedList.isEmpty());
        //6、获取
        System.out.println("获取s2的下标位置:"+linkedList.indexOf(s2));

    }
}
          /*输出结果
元素个数:3
[Student{name=小明, age=20}, Student{name=小红, age=18}, Student{name=小军, age=19}]
--------使用for遍历-----------
Student{name=小明, age=20}
Student{name=小红, age=18}
Student{name=小军, age=19}
--------使用增强for遍历-----------
Student{name=小明, age=20}
Student{name=小红, age=18}
Student{name=小军, age=19}
--------使用迭代器遍历-----------
Student{name=小明, age=20}
Student{name=小红, age=18}
Student{name=小军, age=19}
--------使用列迭代器遍历-----------
Student{name=小明, age=20}
Student{name=小红, age=18}
Student{name=小军, age=19}
判断对象s1是否存在:true
判断元素是否为空:false
获取s2的下标位置:1
            */

LinkedList源码分析

  • int size:集合的大小
  • Node first;:链表的头节点
  • Node last:链表的尾节点
void linkLast(E e) {
    final Node<E> l = last;
    final Node<E> newNode = new Node<>(l, e, null);
    last = newNode;
    if (l == null)
        first = newNode;
    else
        l.next = newNode;
    size++;
    modCount++;
}
private static class Node<E> {
    E item;
    Node<E> next;
    Node<E> prev;

    Node(Node<E> prev, E element, Node<E> next) {
        this.item = element;
        this.next = next;
        this.prev = prev;
    }
}

不同结构实现方式

四、泛型和工具类

介绍泛型

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

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

  • 语法:

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

    • (1)提高代码的重用性
    • (2)防止类型转换异常,提高代码的安全性

创建泛型类

案例一:

package com.mike.test;

/*
        泛型类
        语法:类名<T,E,K...>
        T是类型占位符,表示一种引用类型,如果编写多个,用逗号隔开
 */


public class Test<T> {
    //使用泛型T
    //1、创建变量
    T t;

    //2、作为方法的参数
    public void show(T t){
        System.out.println(t);
    }

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

    public static void main(String[] args){
        //使用泛型类创建对象
        //注意: 1泛型只能使用引用类型,2不同泛型类型对象之间不能相互赋值
        Test<String> test1 = new Test<String>();//jdk1.7之后后面尖括号可写可不写
        test1.t = "hello";
        test1.show("大家好!");
        String t = test1.getT();
        System.out.println(t);

        Test<Integer> test2 = new Test<Integer>();
        test2.t = 100;
        test2.show(200);
        Integer t1 = test2.getT();
        System.out.println(t1);
    }
}


          /*输出结果
                大家好!
                hello
                200
                100
            */

泛型接口

MyInterface接口

package com.mike.test;


/*
        泛型接口
        语法:接口名<T,E,K...>
        注意:不能使用泛型创建静态常量
        T是类型占位符,表示一种引用类型,如果编写多个,用逗号隔开
 */
public interface MyInterface<T> {
    String name = "张三";

    T server(T t);

}

MyInterfaceImpl类

package com.mike.test;

public class MyInterfaceImpl<T> implements MyInterface<T> {
    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}

MyInterfaceImpl2类

package com.mike.test;

public class MyInterfaceImpl2 implements MyInterface<String> {
    @Override
    public String server(String s) {
        System.out.println(s);
        return s;
    }
}

Test类

package com.mike.test;

/*
        泛型类
        语法:类名<T,E,K...>
        T是类型占位符,表示一种引用类型,如果编写多个,用逗号隔开
 */


public class Test implements MyInterface<String> {

    public static void main(String[] args) {
        Test test = new Test();
        test.server("你好!中国!");

        MyInterfaceImpl<Integer> impl = new MyInterfaceImpl<>();
        impl.server(200);

        MyInterfaceImpl2 impl2 = new MyInterfaceImpl2();
        impl2.server("HelloWord");
    }

    @Override
    public String server(String s) {
        System.out.println(s);
        return s;
    }
}
          /*输出结果
                你好!中国!
                200
                HelloWord
            */

泛型方法

MyGenericMethod类

package com.mike.test;
/*
        泛型方法
        语法: <T>返回值类型
*/
public class MyGenericMethod {
    //泛型方法
    public <T> T show(T t){
        System.out.println("泛型方法:"+t);
        return t;
    }
}

Test类

package com.mike.test;


public class Test {
    public static void main(String[] args) {
        //泛型方法的调用
        MyGenericMethod myGenericMethod = new MyGenericMethod();
        myGenericMethod.show("中国加油");
        myGenericMethod.show(200);
        myGenericMethod.show(3.14);
    }
}
          /*输出结果
            泛型方法:中国加油
            泛型方法:200
            泛型方法:3.14
            */

泛型集合

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

  • 特点:

    • 编译时即可检查,而非运行时抛出异常。
    • 访问时,不必类型转换(拆箱)。
    • 不同泛型之间引用不能相互赋值,泛型不存在多态。
package com.mike.test;


import java.util.ArrayList;
import java.util.ListIterator;

public class Test {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("猪八戒");
        arrayList.add("孙悟空");

        for (String s : arrayList) {
            System.out.println(s);
        }

        System.out.println("------------------------------");
        ArrayList<Student> studentArrayList = new ArrayList<Student>();
        Student student1 = new Student("沙僧", 21);
        Student student2 = new Student("唐僧", 20);

        studentArrayList.add(student1);
        studentArrayList.add(student2);
        System.out.println("列迭代器遍历");
        ListIterator<Student> stl = studentArrayList.listIterator();
        while (stl.hasNext()) {
            Student s = stl.next();
            System.out.println(s.toString());
        }
    }
}
          /*输出结果
                猪八戒
                孙悟空
                ------------------------------
                列迭代器遍历
                Student{name=沙僧, age=21}
                Student{name=唐僧, age=20}
            */

五、Set接口与实现类

Set接口

  • 特点:无序、无下标、元素不可重复。
  • 方法:全部继承自Collection中的方法。

Set的使用

package com.mike.test;


import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/*
测试Set接口的使用
特点: (1) 无序、没有下标(2)不能重复
*/



public class Test {
    public static void main(String[] args) {
        //创建集合
        Set<String> set = new HashSet<String>();
        //1.添加数据
        set.add("苹果");
        set.add("菠萝");
        set.add("草莓");

        System.out.println("数据个数:"+set.size());
        System.out.println(set.toString());

        //2.删除
        set.remove("苹果");
        System.out.println("数据个数:"+set.size());
        System.out.println(set.toString());

        //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集合里是否有华为:"+set.contains("菠萝"));
        System.out.println("Set集合是否为空:"+set.isEmpty());
    }
}


          /*输出结果
            数据个数:3
            [苹果, 草莓, 菠萝]
            数据个数:2
            [草莓, 菠萝]
            --------增强for-------
            草莓
            菠萝
            --------迭代器-------
            草莓
            菠萝
            Set集合里是否有华为:true
            Set集合是否为空:false
            */

Set实现类

  • HashSet 【重点】:

    • 基于HashCode实现元素不重复。
    • 当存入元素的哈希码相同时,会调用equals进行确认, 如结果为true, 则拒绝后者存入。
  • TreeSet:

    • 基于排列顺序实现元素不重复。
    • 实现了SortedSet接口, 对集合元素自动排序。
    • 元素对象的类型必须实现Comparable接口,指定排序规则。
    • 通过CompareTo方法确定是否为重复元素。

HashSet使用案例一:

package com.mike.test;


/*
            HashSet集合的使用
            存储结构:哈希表(数组+链表+红黑树(jdk1.8之后))
*/


import java.util.HashSet;
import java.util.Iterator;

public class Test {
    public static void main(String[] args) {
        //新建集合
        HashSet<String> hashSet = new HashSet<String>();
        //1、添加元素
        hashSet.add("刘德华");
        hashSet.add("梁朝伟");
        hashSet.add("林志玲");
        hashSet.add("周润发");
        System.out.println("元素个数:"+hashSet.size());
        System.out.println(hashSet.toString());
        //2、删除数据
        hashSet.remove("刘德华");
        System.out.println("元素个数:"+hashSet.size());
        System.out.println(hashSet.toString());

        //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("该集合是否为空:");


    }
}
          /*输出结果
                元素个数:4
                [林志玲, 梁朝伟, 周润发, 刘德华]
                元素个数:3
                [林志玲, 梁朝伟, 周润发]
                ------增强for-------
                林志玲
                梁朝伟
                周润发
                -------使用迭代器--------
                林志玲
                梁朝伟
                周润发
                该集合中是否添加了郭富城:false
                该集合是否为空:
            */

HashSet使用案例二:

Person类

package com.mike.test;



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 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 (this.name.equals(p.getName())&&this.age==p.getAge()){
                return true;
            }
        }
        return false;
    }




    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

Test类

package com.mike.test;


/*
            HashSet集合的使用
            存储结构:哈希表(数组+链表+红黑树(jdk1.8之后))
            存储过程:(重复依据)
            (1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步。
            (2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
*/


import java.util.HashSet;
import java.util.Iterator;

public class Test {
    public static void main(String[] args) {
        //新建集合
        HashSet<Person> hashSet = new HashSet<Person>();
        //1、添加元素

        Person p1 = new Person("张三", 18);
        Person p2 = new Person("李四", 19);
        Person p3 = new Person("王五", 20);
        Person p4 = new Person("赵六", 21);

        hashSet.add(p1);
        hashSet.add(p2);
        hashSet.add(p3);
        hashSet.add(p4);

        System.out.println("元素个数:"+hashSet.size());
        System.out.println(hashSet.toString());
        //2、删除操作
//        hashSet.remove(p1);
        //当没有重写hashCode()和equals()方法时,下面这个操作是不能删除对象的
        //现在Person类里重写了hashCode()和equals()方法,所以hasSet认为这是集合中的同一个对象
//        hashSet.remove(new Person("赵六", 21));
//        System.out.println("元素个数:"+hashSet.size());
//        System.out.println(hashSet.toString());

//        3、遍历【重点】
//        3.1、增强for
        System.out.println("------增强for-------");
        for (Person p : hashSet) {
            System.out.println(p);
        }

        //3.2、使用迭代器
        System.out.println("-------使用迭代器--------");
        Iterator<Person> it = hashSet.iterator();
        while (it.hasNext()) {
            Person p = it.next();
            System.out.println(p);
        }

        //4判断
//        System.out.println("该集合中是否添加了p1:"+hashSet.contains(p1));
        System.out.println("该集合中是否添加了p3:"+hashSet.contains(new Person("王五", 20)));
        System.out.println("该集合是否为空:"+hashSet.isEmpty());

    }
}
          /*输出结果
            元素个数:4
            [Person{name='张三', age=18}, Person{name='王五', age=20}, Person{name='李			四', age=19}, Person{name='赵六', age=21}]
            ------增强for-------
            Person{name='张三', age=18}
            Person{name='王五', age=20}
            Person{name='李四', age=19}
            Person{name='赵六', age=21}
            -------使用迭代器--------
            Person{name='张三', age=18}
            Person{name='王五', age=20}
            Person{name='李四', age=19}
            Person{name='赵六', age=21}
            该集合中是否添加了p1:true
            该集合是否为空:false
            */

TreeSet使用

package com.mike.test;
/*
            TreeSet集合的使用
            存储结构:红黑树
            存储过程:(重复依据)
            (1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步。
            (2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
*/
import java.util.Iterator;
import java.util.TreeSet;

public class Test {
    public static void main(String[] args) {
        //新建集合
        TreeSet<String> treeSet = new TreeSet<>();
        //1、添加元素
        treeSet.add("xyz");
        treeSet.add("abc");
        treeSet.add("hello");

        System.out.println("元素个数:"+treeSet.size());
        System.out.println(treeSet.toString());
        //2、删除操作
//        treeSet.remove("xyz");
//        System.out.println("删除之后:"+treeSet.toString());
//        System.out.println("元素个数:"+treeSet.size());

//        3、遍历【重点】
//        3.1、增强for
        System.out.println("------增强for-------");
        for (String p : treeSet) {
            System.out.println(p);
        }

        //3.2、使用迭代器
        System.out.println("-------使用迭代器--------");
        Iterator<String> it = treeSet.iterator();
        while (it.hasNext()) {
            String p = it.next();
            System.out.println(p);
        }

        //4判断
        System.out.println("该集合中是否添加了abc:"+treeSet.contains("abc"));
        System.out.println("该集合是否为空:"+treeSet.isEmpty());
    }
}
          /*输出结果
                元素个数:3
                [abc, hello, xyz]
                ------增强for-------
                abc
                hello
                xyz
                -------使用迭代器--------
                abc
                hello
                xyz
                该集合中是否添加了abc:true
                该集合是否为空:false
            */

用TreeSet集合添加对象

Person类

package com.mike.test;

import java.util.Objects;

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 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 o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;

        Person person = (Person) o;

        if (age != person.age) return false;
        return name.equals(person.name);
    }


    @Override
    public int hashCode() {
        int result = name.hashCode();
        result = 31 * result + age;
        return result;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

//    先按姓名比,然后再按年龄比
    @Override
    public int compareTo(Person o) {
        int n1 = this.getName().compareTo(o.getName());
        int n2 = this.age-o.getAge();
        return n1== 0 ? n2 : n1;
    }
}

Test类

package com.mike.test;
/*
            TreeSet集合的使用
            存储结构:红黑树
            要求:元素必须要实现Comparable接日, compareTo()方法返回值为0,认为是重复元素
*/

import java.util.Iterator;
import java.util.TreeSet;

public class Test {
    public static void main(String[] args) {
        //新建集合
        TreeSet<Person> treeSet = new TreeSet<Person>();
        //1、添加元素

        Person p1 = new Person("刘德华", 55);
        Person p2 = new Person("谢霆锋", 56);
        Person p3 = new Person("郭富城", 57);
        Person p4 = new Person("周润发", 58);


        treeSet.add(p1);
        treeSet.add(p2);
        treeSet.add(p3);
        treeSet.add(p4);

        System.out.println("元素个数:"+treeSet.size());
        System.out.println(treeSet.toString());
        //2、删除操作
//        treeSet.remove(p1);
//        treeSet.remove(new Person("周润发", 58));//这样删除也是可以的,因为重写了equals和hashcode
//        System.out.println("删除之后:"+treeSet.toString());
//        System.out.println("元素个数:"+treeSet.size());

//        3、遍历【重点】
//        3.1、增强for
        System.out.println("------增强for-------");
        for (Person p : treeSet) {
            System.out.println(p);
        }

        //3.2、使用迭代器
        System.out.println("-------使用迭代器--------");
        Iterator<Person> it = treeSet.iterator();
        while (it.hasNext()) {
            Person p = it.next();
            System.out.println(p);
        }

        //4判断
        System.out.println("该集合中是否添加了p1:"+treeSet.contains(p1));
        System.out.println("该集合是否为空:"+treeSet.isEmpty());
    }
}


          /*输出结果
元素个数:4
[Person{name='刘德华', age=55}, Person{name='周润发', age=58}, Person{name='谢霆锋', age=56}, Person{name='郭富城', age=57}]
------增强for-------
Person{name='刘德华', age=55}
Person{name='周润发', age=58}
Person{name='谢霆锋', age=56}
Person{name='郭富城', age=57}
-------使用迭代器--------
Person{name='刘德华', age=55}
Person{name='周润发', age=58}
Person{name='谢霆锋', age=56}
Person{name='郭富城', age=57}
该集合中是否添加了p1:true
该集合是否为空:false
            */

Comparator :实现定制比较(比较器)

package com.mike.test;


/*
            TreeSet集合的使用
            Comparator :实现定制比较(比较器)
            Comparable:可比较的
*/

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

public class Test {
    public static void main(String[] args) {
        //创建集合,并指定比较规则
        TreeSet<Person> treeSet = 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("xyz", 20);
        Person p2 = new Person("hello", 22);
        Person p3 = new Person("zhangsan", 25);

        treeSet.add(p1);
        treeSet.add(p2);
        treeSet.add(p3);

        System.out.println("元素个数:"+treeSet.size());
        System.out.println(treeSet.toString());
    }
}
           /*输出结果
元素个数:3
[Person{name='xyz', age=20}, Person{name='hello', age=22}, Person{name='zhangsan', age=25}]
            */

TreeSet小案例

  • 要求:使用TreeSet集合实现字符串按照长度进行排序
  • helloworld zhang lisi wangwu beijing xian nanjing
package com.mike.test;

import java.util.Comparator;
import java.util.TreeSet;

//要求:使用TreeSet集合实现字符串按照长度进行排序
//helloworld  zhang  lisi  wangwu  beijing  xian  nanjing
//Comparator接口实现定制比较

public class Demo01 {
    public static void main(String[] args) {
        //创建集合,并指定比较规则
        TreeSet<String> treeSet = 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);//调用compareTo自己的规则
                return n1==0?n2:n1;
            }
        });
        //添加数据
        treeSet.add("helloworld");
        treeSet.add("zhang");
        treeSet.add("lisi");
        treeSet.add("wangwu");
        treeSet.add("beijing");
        treeSet.add("xian");
        treeSet.add("nanjing");

        System.out.println(treeSet.toString());
    }
}
        /*输出结果:
        [lisi, xian, zhang, wangwu, beijing, nanjing, helloworld]
        */

六、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集合。

Map接口的使用

遍历效率:keySet()<entrySet()

package com.mike.test;

/*
        Map接口的使用
        特点:(1)存储键值对(2)键不能重复,值可以重复(3)无序
*/

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Demo01 {
    public static void main(String[] args) {
        //创建Map集合
        Map<String,String> map = new HashMap<>();
        //1、添加元素
        map.put("CN","中国");
        map.put("US","美国");
        map.put("UK","英国");
        map.put("FR","法国");
        map.put("CA","加拿大");
        map.put("IT","意大利");

        System.out.println("元素个数:"+map.size());
        System.out.println(map.toString());

        //2、删除
//        map.remove("IT");
//        System.out.println("------删除Key=IT后------");
//        System.out.println("元素个数:"+map.size());
//        System.out.println(map.toString());

        //3、遍历
        //3.1、使用keySet();
        System.out.println("----------1、使用keySet()遍历----------");
        Set<String> keySet = map.keySet();
        for (String s : keySet) {
            System.out.println(s+"="+map.get(s));
        }
        //3.2、使用entrySet()方法
        System.out.println("----------2、使用entrySet()方法遍历----------");
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            System.out.println(entry.getKey()+"="+entry.getValue());
        }

        //4、判断
        System.out.println(map.containsKey("CN"));
        System.out.println(map.containsValue("泰国"));
    }
}
/*
            元素个数:6
            {UK=英国, CN=中国, IT=意大利, FR=法国, US=美国, CA=加拿大}
            ----------1、使用keySet()遍历----------
            UK=英国
            CN=中国
            IT=意大利
            FR=法国
            US=美国
            CA=加拿大
            ----------2、使用entrySet()方法遍历----------
            UK=英国
            CN=中国
            IT=意大利
            FR=法国
            US=美国
            CA=加拿大
            true
            false
*/

Map集合的实现类

  • HashMap 【重点】
    • JDK1. 2版本,线程不安全,运行效率快;
    • 允许用null作为key或是value。
    • HashMap的无参构造默认初始容量是16,默认加载因子(0.75) 的空HashMap。

加载因子: 加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度。如果当哈希表中的条目数超出了 加载因子与当前容量的乘积时,则要对该哈希表进行rehash()操作,从而哈希表将具有大约两倍的桶数。

  • Hashtable:

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

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

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

HashMap的使用

Student类

package com.mike.test;

import java.util.Objects;

public class Student {
    private int stuNo;
    private String name;

    public Student() {
    }

    public Student(int stuNo, String name) {
        this.stuNo = stuNo;
        this.name = name;
    }

    public int getStuNo() {
        return stuNo;
    }

    public void setStuNo(int stuNo) {
        this.stuNo = stuNo;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Student)) return false;

        Student student = (Student) o;

        if (stuNo != student.stuNo) return false;
        return name.equals(student.name);
    }

    @Override
    public int hashCode() {
        int result = stuNo;
        result = 31 * result + name.hashCode();
        return result;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuNo=" + stuNo +
                ", name='" + name + '\'' +
                '}';
    }
}

Demo01类

package com.mike.test;

/*
        HashMap集合的使用
        存储结构:哈希表(数组+链表+红黑树)
        使用key可hashcode和equals作为重复


*/

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Demo01 {
    public static void main(String[] args) {
        //创建Map集合
        HashMap<Student,String> students = new HashMap<Student,String>();
        //1、添加元素

        Student s1 = new Student(001, "孙悟空");
        Student s2 = new Student(002, "唐三藏");
        Student s3 = new Student(003, "猪八戒");
        Student s4 = new Student(004, "沙和尚");
        Student s5 = new Student(005, "白龙马");

        students.put(s1,"北京");
        students.put(s2,"南京");
        students.put(s3,"河北");
        students.put(s4,"河南");
        students.put(s5,"上海");

        System.out.println("元素个数:"+students.size());
        System.out.println(students.toString());

        //2、删除
        students.remove(s1);
        System.out.println("------删除Key=s1后------");
        System.out.println("元素个数:"+students.size());
        System.out.println(students.toString());

        //3、遍历
        //3.1、使用keySet();
        System.out.println("----------1、使用keySet()遍历----------");
        Set<Student> keySet = students.keySet();
        for (Student s : keySet) {
            System.out.println(s+"="+students.get(s));
        }
        //3.2、使用entrySet()方法
        System.out.println("----------2、使用entrySet()方法遍历----------");
        Set<Map.Entry<Student, String>> entries = students.entrySet();
        for (Map.Entry<Student, String> entry : entries) {
            System.out.println(entry.getKey()+"="+entry.getValue());
        }

        //4、判断
        System.out.println(students.containsKey(s1));
        System.out.println(students.containsValue("上海"));
    }
}
 /*输出结果
元素个数:5
{Student{stuNo=1, name='孙悟空'}=北京, Student{stuNo=4, name='沙和尚'}=河南, Student{stuNo=3, name='猪八戒'}=河北, Student{stuNo=5, name='白龙马'}=上海, Student{stuNo=2, name='唐三藏'}=南京}
------删除Key=s1后------
元素个数:4
{Student{stuNo=4, name='沙和尚'}=河南, Student{stuNo=3, name='猪八戒'}=河北, Student{stuNo=5, name='白龙马'}=上海, Student{stuNo=2, name='唐三藏'}=南京}
----------1、使用keySet()遍历----------
Student{stuNo=4, name='沙和尚'}=河南
Student{stuNo=3, name='猪八戒'}=河北
Student{stuNo=5, name='白龙马'}=上海
Student{stuNo=2, name='唐三藏'}=南京
----------2、使用entrySet()方法遍历----------
Student{stuNo=4, name='沙和尚'}=河南
Student{stuNo=3, name='猪八戒'}=河北
Student{stuNo=5, name='白龙马'}=上海
Student{stuNo=2, name='唐三藏'}=南京
false
true
*/

Map源码分析

1 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;/ /hashMap初始容量大小
2 static final int MAXIMUM_CAPACITY = 1 << 30;/ /hashmap的数组最大容量
3 static final float DEFAULT_LOAD_ FACTOR = 0.75f; //默认加载因子
4 static final int TREEIFY_THRESHOLD = 8;//jdk1.8 当链表长度大于8时,调整成红黑数
5 static final int UNTREEIFY_THRESHOLD = 6;; //jdk1.8 当链表长度小于6时,调整成链表
6 static final int MIN.TREEIFY_CAPACITY = 64;//jdk1.8 当链表长度大于8时,并且集合元素个数大于等于64时,调整成红黑数
7 transient Node<K,V>[] table;//哈希表中的数组
8 size;//元素个数
HashMap无参构造

刚创建HashMap之后没有添加元素table=null,size=0。(目的:节省空间)

public HashMap() {
        this.loadFactor = DEFAULT_LOAD_FACTOR;//all other fields defaulted
    }
put方法
public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
   }

HashMap总结

(1)HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
(2)当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数。
(3)jdk1.8每个链表长度大于8,并且元素个数大于等于64时,会调整为红黑树,目的提高执行效率
(4)jdk1.8当链表长度小于6时,调整成链表
(5)jdk1.8以前,链表是头插入,jdk1.8以后时是尾插入

Hashtable和Propertiles

  • Hashtable

    • 此类实现一个哈希表,该哈希表将键映射到相应的值。任何非nul1对象都可以用作键或值。
    • 为了成功地在哈希表中存储和获取对象,用作键的对象必须实现hashCode方法和equals 方法。
  • Propertiles

    • Properties类表示了一个持久的属性集。Properties 可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串 。
    • 一个属性列表可包含另一个属性列表作为它的“默认值”;如果未能在原有的属性列表中搜索到属性键,则搜索第二个属性列表。

这里暂时认识一下Hashtable和Propertiles。

TreeMap的使用

Student类

package com.mike.test;

import java.util.Objects;

public class Student implements Comparable<Student> {
    private int stuNo;
    private String name;

    public Student() {
    }

    public Student(int stuNo, String name) {
        this.stuNo = stuNo;
        this.name = name;
    }

    public int getStuNo() {
        return stuNo;
    }

    public void setStuNo(int stuNo) {
        this.stuNo = stuNo;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Student)) return false;

        Student student = (Student) o;

        if (stuNo != student.stuNo) return false;
        return name.equals(student.name);
    }

    @Override
    public int hashCode() {
        int result = stuNo;
        result = 31 * result + name.hashCode();
        return result;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuNo=" + stuNo +
                ", name='" + name + '\'' +
                '}';
    }

    @Override
    public int compareTo(Student o) {
        int n1 = this.stuNo-o.getStuNo();
        return n1;
    }
}

Demo01类

package com.mike.test;

/*
        TreeMap的使用
        存储结构:红黑树

*/

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class Demo01 {
    public static void main(String[] args) {
        //创建Map集合
        TreeMap<Student,String> treeMap = new TreeMap<Student,String>();
/*或者直接用匿名内部类
 TreeMap<Student,String> treeMap = new TreeMap<Student,String>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return 0;//在这里写比较规则
            }
        });
*/
        //1、添加元素
        Student s1 = new Student(001, "孙悟空");
        Student s2 = new Student(002, "唐三藏");
        Student s3 = new Student(003, "猪八戒");
        Student s4 = new Student(004, "沙和尚");
        Student s5 = new Student(005, "白龙马");

        treeMap.put(s1,"北京");
        treeMap.put(s2,"南京");
        treeMap.put(s3,"河北");
        treeMap.put(s4,"河南");
        treeMap.put(s5,"上海");

       
        System.out.println("元素个数:"+treeMap.size());
        //要实现Student类的compareTo()方法,让Student类继承Comparable
        //定制比较规则
        System.out.println(treeMap.toString());

        //2、删除
//        treeMap.remove(s1);
//        System.out.println("------删除Key=s1后------");
//        System.out.println("元素个数:"+treeMap.size());
//        System.out.println(treeMap.toString());

        //3、遍历
        //3.1、使用keySet();
        System.out.println("----------1、使用keySet()遍历----------");
        Set<Student> keySet = treeMap.keySet();
        for (Student s : keySet) {
            System.out.println(s+"="+treeMap.get(s));
        }
        //3.2、使用entrySet()方法
        System.out.println("----------2、使用entrySet()方法遍历----------");
        Set<Map.Entry<Student, String>> entries = treeMap.entrySet();
        for (Map.Entry<Student, String> entry : entries) {
            System.out.println(entry.getKey()+"="+entry.getValue());
        }

        //4、判断
        System.out.println(treeMap.containsKey(s1));
        System.out.println(treeMap.containsValue("上海"));
    }
}
 /*输出结果
元素个数:5
{Student{stuNo=1, name='孙悟空'}=北京, Student{stuNo=2, name='唐三藏'}=南京, Student{stuNo=3, name='猪八戒'}=河北, Student{stuNo=4, name='沙和尚'}=河南, Student{stuNo=5, name='白龙马'}=上海}
----------1、使用keySet()遍历----------
Student{stuNo=1, name='孙悟空'}=北京
Student{stuNo=2, name='唐三藏'}=南京
Student{stuNo=3, name='猪八戒'}=河北
Student{stuNo=4, name='沙和尚'}=河南
Student{stuNo=5, name='白龙马'}=上海
----------2、使用entrySet()方法遍历----------
Student{stuNo=1, name='孙悟空'}=北京
Student{stuNo=2, name='唐三藏'}=南京
Student{stuNo=3, name='猪八戒'}=河北
Student{stuNo=4, name='沙和尚'}=河南
Student{stuNo=5, name='白龙马'}=上海
true
true
*/

Colletions工具类

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

  • 方法:

public static void reverse(List<?> list) //反转集合中元素的顺序
public static void shuffle(List<?> list) //随机重置集合元素的顺序
public static void sort(List<T> list) //升序排序(元素类型必须实现Comparable接口)

演示Collections工具类的使用

package com.mike.test;

/*
           演示Collections工具类的使用
*/

import java.util.*;

public class Test {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(20);
        list.add(3);
        list.add(35);
        list.add(66);
        list.add(50);

        //sort排序
        System.out.println("-----排序前------");
        System.out.println(list.toString());
        Collections.sort(list);
        System.out.println("-----排序后------");
        System.out.println(list.toString());

        //binarySearch二分查找(只能用在有序的集合中)
        int i = Collections.binarySearch(list, 66);
        System.out.println("66的位置:"+i);

        //copy复制
        List<Integer> list2 = new ArrayList<Integer>();
        for (int k = 0; k < list.size(); k++) {
            list2.add(0);
        }
        Collections.copy(list2,list);
        System.out.println("-----复制后------");
        System.out.println(list2.toString());

        //reverse反转
        Collections.reverse(list);
        System.out.println("-----反转后------");
        System.out.println(list.toString());


        //shuffle 打乱
        Collections.shuffle(list);
        System.out.println("-----打乱后------");//每次运行都不一样
        System.out.println(list.toString());


        //补充:list转成数组
        System.out.println("-----list转成数组------");
        Integer[] arr = list.toArray(new Integer[0]);
        System.out.println("长度:"+arr.length);
        System.out.println(Arrays.toString(arr));

        //数组转成集合
        String[] names = {"张三","李四","王五","赵六"};
        for (String name : names) {
            System.out.println(name);
        }
        System.out.println("-----数组转成集合------");
        //集合是一个受限集合,不能添加和删除
        List<String> strings = Arrays.asList(names);
        System.out.println(strings.toString());

        //把基本类型数组转成集合时,需要修改为包装类型
        Integer[] nums = {100,200,300,400,500};
        List<Integer> ints = Arrays.asList(nums);
        System.out.println(ints);
    }
}
           /*输出结果
                -----排序前------
                [20, 3, 35, 66, 50]
                -----排序后------
                [3, 20, 35, 50, 66]
                66的位置:4
                -----复制后------
                [3, 20, 35, 50, 66]
                -----反转后------
                [66, 50, 35, 20, 3]
                -----打乱后------
                [66, 35, 20, 3, 50]
                -----list转成数组------
                长度:5
                [66, 35, 20, 3, 50]
                张三
                李四
                王五
                赵六
                -----数组转成集合------
                [张三, 李四, 王五, 赵六]
                [100, 200, 300, 400, 500]
            */

集合总结

  • 集合的概念:

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

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

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

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

    • 集合工具类,定义了除了存取以外的集合常用方法。
posted @ 2022-03-09 23:23  海边蓝贝壳  阅读(37)  评论(0编辑  收藏  举报