Java集合学习笔记。

一、集合的概念

什么是集合

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

  • 和数组的区别:

    1. 数组长度固定,集合长度不固定。
    2. 数组可以存储基本类型和引用类型,集合只能存储引用类型.
  • 位置:java.util.*;

二、Collection接口

Collection体系集合

在这里插入图片描述

Collection父接口

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

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();
        //1.添加元素
        collection.add("苹果");
        collection.add("西瓜");
        collection.add("榴莲");
        System.out.println("元素个数:"+collection.size());
        System.out.println(collection);

        //2.删除元素
        /*System.out.println("================================");
        collection.remove("榴莲");
        collection.clear();
        System.out.println("删除之后:"+collection.size());*/

        //3.遍历元素(重点)
        System.out.println("=================================");
        //3.1.使用增强for循环
        for (Object o : collection) {
            System.out.println(o);
        }
        //3.2.使用迭代器(迭代器专门用来遍历集合的一种方式)
        //hasNext();有没有下一个元素
        //next();获取下一个元素
        //remove();删除当前元素
        System.out.println("==================================");
        Iterator it = collection.iterator();
        while (it.hasNext()){
            String s = (String)it.next();
            System.out.println(s);
            //不能使用collection删除方法
            //collection.remove(s);//并发修改异常
            it.remove();
        }
        System.out.println("元素个数:"+collection.size());

        //4.判断
        System.out.println("==================================");
        System.out.println(collection.contains("西瓜"));
        System.out.println(collection.isEmpty());


    }
}

package 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 collection;

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("卡萨丁",20);
        Student s2 = new Student("杰斯",20);
        Student s3 = new Student("亚索",20);
        //1.添加数据
        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        System.out.println("元素个数:"+collection.size());
        System.out.println(collection.toString());

        //2.删除
        /*collection.remove(s1);
        System.out.println("==================================");
        collection.remove(new Student("卡萨丁",20));
        collection.clear();//只是删除了地址,并没有删除对象
        System.out.println("删除之后:"+collection.size());*/

        //3.遍历
        //3.1 增强for
        System.out.println("==================================");
        for (Object o : collection) {
            Student s = (Student)o;
            System.out.println(s.toString());
        }
        //3.2 迭代器:hasNext();   next();     remove();     迭代过程中不能使用collection的删除方法
        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(collection.contains(s1));
        System.out.println(collection.isEmpty());


    }
}

三、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) //返回from Index和toIndex之间的集合元素。
package collection;

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

//List接口的使用
//特点:1.有序、有下标 2.可以重复
public class Demo03 {
    public static void main(String[] args) {
        //先创建集合对象
        List list = new ArrayList<>();
        //1.添加元素
        list.add("苹果");
        list.add("小米");
        list.add("华为");
        System.out.println("元素个数:"+list.size());
        System.out.println(list.toString());

        //2.删除元素
        /*list.remove("华为");
        list.remove(0);
        System.out.println("删除之后:"+list.size());
        System.out.println(list.toString());*/

        //3.遍历
        //3.1使用for遍历
        System.out.println("====================================");
        for (int i = 0; i <list.size() ; i++) {
            System.out.println(list.get(i));
        }
        //3.2使用增强for
        System.out.println("====================================");
        for (Object o : list) {
            System.out.println(o);
        }
        //3.3使用迭代器
        System.out.println("====================================");
        Iterator it = list.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        //3.4使用列表迭代器,和Itertor的区别:ListIterator可以向前或向后遍历、添加、删除、修改元素
        System.out.println("====================================");
        ListIterator lit = list.listIterator();
        while (lit.hasNext()){
            System.out.println(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("====================================");
        System.out.println(list.indexOf("小米"));


    }
}

package collection;

import java.util.ArrayList;
import java.util.List;

//List的使用
public class Demo04 {
    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.size());
        System.out.println(list.toString());

        //2.删除操作
        /*list.remove(0);
        //list.remove((Object)20);
        //list.remove(new Integer(20));
        System.out.println("删除之后:"+list.size());
        System.out.println(list.toString());*/

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


    }
}

List实现类

  • ArrayList(重点):

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

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

    • 链表结构实现,查询慢、增删快;
    • JDK1.2 版本支持,运行效率快、线程不安全。

ArrayList的使用

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


    @Override
    public boolean equals(Object obj) {
        //1.判断两个对象是否是同一个引用
        if (this == obj) {
            return true;
        }
        //2.判断obj是否null
        if (obj==null){
            return false;
        }
        //3.判断是否是同一个类型
        // if (this.getClass()==obj.getClass()){}

        //intanceof   判断对象是否是某种类型
        if (obj instanceof Student){
            //4.强制转换类型
            Student s=(Student)obj;
            //5.比较属性
            if (this.name.equals(s.getName())&&this.age==s.getAge()){     //字符串的比较用equals
                return true;
            }
        }
        //不满足条件返回false
        return false;
    }
}

package collection;

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

//ArrayList的使用
//储存结构;数组,查找遍历速度快,增删慢
public class Demo05 {
    public static void main(String[] args) {
        //创建集合
        ArrayList arrayList = new ArrayList<>();
        //1.添加元素
        Student s1 = new Student("食发鬼",20);
        Student s2 = new Student("圣迭戈",22);
        Student s3 = new Student("郭德纲",24);
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        System.out.println("元素个数:"+arrayList.size());
        System.out.println(arrayList.toString());

        //2.删除元素
        /*arrayList.remove(new Student("食发鬼",20));//里面有equals(this==obj)这个方法
        System.out.println("删除之后:"+arrayList.size());*/

        //3.遍历元素(重点)
        //3.1使用迭代器
        System.out.println("======================================");
        Iterator it = arrayList.iterator();
        while(it.hasNext()){
            Student s = (Student)it.next();
            System.out.println(s.toString());
        }
        //3.2列表迭代器
        System.out.println("======================================");
        ListIterator lit = arrayList.listIterator();
        while(lit.hasNext()){
            Student s = (Student)lit.next();
            System.out.println(s.toString());
        }
        System.out.println("======================================");
        while(lit.hasPrevious()){
            Student s = (Student)lit.previous();
            System.out.println(s.toString());
        }

        //4.判断
        System.out.println(arrayList.contains(new Student("圣迭戈",22)));
        System.out.println(arrayList.isEmpty());

        //5.查找
        System.out.println(arrayList.indexOf(new Student("圣迭戈",22)));

    }
}

ArrayList源码分析

  • DEFAULT_CAPACITY=10;默认容量。

    • 注意:如果没有向集合中添加任何元素时,容量0;添加一个元素之后,容量为10;每次扩容大写是原来的1.5倍。
  • elementData 存放元素的数组。

  • size 实际元素的个数。

  • add() 添加元素

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

private void ensureCapacityInternal(int minCapacity) {
        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

Vector的使用

package collection;

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

//演示Vector集合的使用
//存储结构:数组
public class Demo06 {
    public static void main(String[] args) {
        //创建集合
        Vector vector = new Vector<>();
        //1.添加元素
        vector.add("草莓");
        vector.add("芒果");
        vector.add("西瓜");
        System.out.println("元素个数:"+vector.size());
        System.out.println(vector.toString());

        //2.删除
        /*vector.remove(0);
        vector.remove("西瓜");
        vector.clear();*/

        //3.遍历
        //使用枚举器
        Enumeration en = vector.elements();
        while (en.hasMoreElements()){
            String o = (String)en.nextElement();
            System.out.println(o);
        }

        //4.判断
        System.out.println(vector.contains("西瓜"));
        System.out.println(vector.isEmpty());

        //5.vector其他方法
        //firstElement、lastElement、elementAt();

    }
}

LinkedList的使用

package collection;

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

//ListedList的使用
//存储结构:双向链表
public class Demo07 {
    public static void main(String[] args) {
        //创建集合
        LinkedList linkedList = new LinkedList<>();
        //1.添加元素
        Student s1 = new Student("刘德华",20);
        Student s2 = new Student("郭富城",22);
        Student s3 = new Student("梁朝伟",18);
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        linkedList.add(s3);
        System.out.println("元素个数:"+linkedList.size());
        System.out.println(linkedList.toString());

        //2.删除
        /*System.out.println("=======================================");
        linkedList.remove(new Student("刘德华",20));
        System.out.println("删除之后:"+linkedList.size());
        linkedList.clear();
        System.out.println("删除之后:"+linkedList.size());*/

        //3.遍历
        //3.1for遍历
        System.out.println("=======================================");
        for (int i = 0; i <linkedList.size() ; i++) {
            System.out.println(linkedList.get(i));
        }
        //3.2增强for
        System.out.println("=======================================");
        for (Object o : linkedList) {
            Student s = (Student)o;
            System.out.println(s.toString());
        }
        //3.3使用迭代器
        System.out.println("=======================================");
        Iterator it = linkedList.iterator();
        while(it.hasNext()){
            Student s = (Student)it.next();
            System.out.println(s.toString());
        }
        //3.4使用列表迭代器
        System.out.println("=======================================");
        ListIterator lit = linkedList.listIterator();
        while (lit.hasNext()){
            Student s = (Student)lit.next();
            System.out.println(s.toString());
        }

        //4.判断
        System.out.println(linkedList.contains(s1));
        System.out.println(linkedList.isEmpty());

        //5.获取
        System.out.println(linkedList.indexOf(s3));

    }
}

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

ArrayList和LinkedList的区别

在这里插入图片描述

四、泛型和工具类

  • Java 泛型是JDK1.5中引入的一个新特性,本质是参数化类型,把类型作为参数传递。
  • 常见形式有泛型类、泛型接口、泛型方法。
  • 语法:<T,….> T称为类型占位符,表示一种引用类型。
  • 好处:
    • 提高代码的重用性;
    • 防止类型转换异常,提高代码的安全性。

泛型类

package generic;

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

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

    //2.泛型作为方法的参数
    public void show(T t){
        //T t1 = new T();//不能new对象,因为T不确定。
        System.out.println(t);
    }

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

泛型接口

package generic;

//泛型接口
//语法:接口名<T>
//注意:不能泛型静态常量

public interface MyInterface<T> {
    String name = "张三";

    T server(T t);
}

package generic;

public class MyInterfaceImpl implements MyInterface<String > {

    @Override
    public String server(String t) {
        System.out.println(t);
        return t;
    }
}

package generic;

public class MyInterfaceImpl2<T> implements MyInterface<T>{

    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}

泛型方法

package generic;

//泛型方法
//语法:<T> 返回值类型
public class MyGenericMethod{

    //泛型方法
    public <T>  T show(T t){
        System.out.println("泛型方法:"+t);
       return t;
    }
}

package generic;

public class TextGeneric {
    public static void main(String[] args) {
        //使用泛型类创建对象
        //注意:1.泛型只能使用引用类型。2.不同泛型之间不能相互赋值
        MyGeneric<String> myGeneric = new MyGeneric<>();
        myGeneric.t= "hello";
        myGeneric.show("大家好,加油");
        String string = myGeneric.getT();

        MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>();
        myGeneric1.t = 100;
        myGeneric1.show(200);
        Integer integer = myGeneric1.getT();


        //泛型接口
        System.out.println("===================================");
        MyInterfaceImpl impl = new MyInterfaceImpl();
        impl.server("xxxxxxx");

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



        //泛型方法
        System.out.println("===================================");
        MyGenericMethod myGenericMethod = new MyGenericMethod();
        myGenericMethod.show("中国加油");//这里输入什么就是什么类型
        myGenericMethod.show(200);
        myGenericMethod.show(3.14);


    }
}

泛型集合

  • 概念

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

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

import collection.Student;

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

public class Demo01 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<String>();
        arrayList.add("xxx");
        arrayList.add("yyy");
        //arrayList.add(10);//有<String>约束这个就添加不了了。
        //arrayList.add(20);

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

        ArrayList<Student> arrayList1 = new ArrayList<Student>();
        Student s1 = new Student("刘德华",20);
        Student s2 = new Student("郭富城",22);
        Student s3 = new Student("梁朝伟",18);
        arrayList1.add(s1);
        arrayList1.add(s2);
        arrayList1.add(s3);

        Iterator<Student> it = arrayList1.iterator();
        while(it.hasNext()){
            Student student= it.next();
            System.out.println(student.toString());
        }


    }
}

五、Set接口与实现类

Set子接口

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


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

//测试Set接口的使用
//特点:1.无序、没有下标。2.不能重复
public class Demo01 {
    public static void main(String[] args) {
        //创建集合
        HashSet set = new HashSet<>();
        //1.添加数据
        set.add("小米");
        set.add("华为");
        set.add("苹果");
        System.out.println("数据个数:"+set.size());
        System.out.println(set.toString());

        //2.删除数据
        /*set.remove("小米");
        System.out.println(set.toString());*/

        //3.遍历(重点)
        //3.1使用增强for   ,不能使用for循环,因为它无序没有下标
        System.out.println("======================================");
        for (Object o : set) {
            System.out.println(o);
        }
        //3.2使用迭代器
        System.out.println("======================================");
        Iterator<String> iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        //4.判断
        System.out.println(set.contains("华为"));
        System.out.println(set.isEmpty());

    }
}

Set实现类

  • HashSet(重点):

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

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

HashSet的使用

package collection2;

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

//HashSet集合的使用
//存储结构:哈希表(数组+链表+红黑树)
public class Demo02 {
    public static void main(String[] args) {
        //新建集合
        HashSet<String> hashSet = new HashSet<String>();
        //1.添加元素
        hashSet.add("泰勒");
        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());*/

        //3.遍历操作
        //3.1 增强for
        System.out.println("==================================");
        for (String s : hashSet) {
            System.out.println(s);
        }
        //3.2 使用迭代器
        System.out.println("==================================");
        Iterator iterator = hashSet.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //4.判断
        System.out.println("==================================");
        System.out.println(hashSet.contains("傅里叶"));
        System.out.println(hashSet.isEmpty());


    }
}

package collection2;

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

//HashSet集合的使用
//存储结构:哈希表(数组+链表+红黑树)
//存储过程(重复依据)
//1.根据hascode计算保存的位置,如果此位置为空,则直接保存、如果不为空执行第二部
//2.在执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
public class Demo03 {
    public static void main(String[] args) {
        //创建集合
        HashSet<Person> person = new HashSet<>();
        //1.添加元素
        Person p1 = new Person("哈士奇",20);
        Person p2 = new Person("萨摩耶",30);
        Person p3 = new Person("阿拉斯加",30);
        person.add(p1);
        person.add(p2);
        person.add(p3);
        //person.add(p3);//不能重复
        person.add(new Person("哈士奇",20));

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

        //删除操作
        /*person.remove(p3);
        person.remove(new Person("哈士奇",20));
        System.out.println("删除之后:"+person.size());
        System.out.println("删除之后:"+person.toString());*/

        //3遍历(重点)
        //3.1  使用增强for
        System.out.println("==============================");
        for (Person person1 : person) {
            System.out.println(person1.toString());
        }
        //3.2 迭代器
        System.out.println("==============================");
        Iterator iterator = person.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //4.判断
        System.out.println("==============================");
        System.out.println(person.contains(new Person("哈士奇",20)));
        System.out.println(person.isEmpty());
    }
}

  • HashSet存储方式

在这里插入图片描述

package collection2;

import java.util.Objects;

//人类
public class Person implements Comparable<Person>{
    private  String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public 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 &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
        //补充:里面用到了一个数:31
        //1.31是一个质数,减少数列冲突
        //2.31是提高执行效率     31*i=(i<<5)-i
    }

    /*@Override
    public int hashCode() {
        int n1 = this.name.hashCode();
        int n2 = this.age;
        return n1+n2;
    }

    @Override
    public boolean equals(Object obj) {
        //1.判断两个对象是否是同一个引用
        if (this == obj) {
            return true;
        }
        //2.判断obj是否null
        if (obj == null) {
            return false;
        }
        //3.判断是否是同一个类型
        // if (this.getClass()==obj.getClass()){}

        //intanceof   判断对象是否是某种类型
        if (obj instanceof Person) {
            //4.强制转换类型
            Person s = (Person) obj;
            //5.比较属性
            if (this.name.equals(s.getName()) && this.age == s.getAge()) {     //字符串的比较用equals
                return true;
            }
        }
        //不满足条件返回false
        return false;
    }*/

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

TreeSet的使用

package collection2;

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

/**
 * TreeSet的使用
 * 存储结构:红黑树
 */
public class Demo04 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<String> treeSet = new TreeSet<>();
        //1.添加元素
        treeSet.add("xyz");
        treeSet.add("abc");
        treeSet.add("hello");
        treeSet.add("hello");
        System.out.println("元素个数:"+treeSet.size());
        System.out.println(treeSet.toString());

        //2.删除
        /*treeSet.remove("xyz");
        System.out.println("删除之后:"+treeSet.size());*/

        //3.遍历
        //3.1 使用增强for
        System.out.println("===========================");
        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());
        }

        //4.判断
        System.out.println("===========================");
        System.out.println(treeSet.contains("abc"));
    }
}

package collection2;

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

/**
 * 使用TreeSet保存数据
 * 存储结构:红黑树
 * 要求:元素必须要实现Comparable接口,compareTo()方法返回值为0,认为是重复元素
 */
public class Demo05 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<Person> persons = new TreeSet<>();
        //1.添加元素
        Person p2 = new Person("萨摩耶",30);
        Person p3 = new Person("阿拉斯加",40);
        Person p4 = new Person("阿拉斯加",30);
        Person p1 = new Person("哈士奇",20);
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);
        System.out.println("元素个数:"+persons.size());
        System.out.println(persons.toString());

        //2.删除
        /*persons.remove(p1);
        System.out.println(persons.size());*/

        //3.遍历
        //3.1使用增强for
        System.out.println("==========================");
        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("==========================");
        System.out.println(persons.contains(new Person("萨摩耶",30)));

    }
}

  • Comparator接口
package collection2;

import sun.reflect.generics.tree.Tree;

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>() {
            @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 p2 = new Person("xyz",30);
        Person p3 = new Person("helli",40);
        Person p4 = new Person("zhangsan",30);
        Person p1 = new Person("lisi",30);
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);
        System.out.println(persons.toString());
    }
}
  • TreeSet案例
package collection2;

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

/**
 * 要求:使用TreeSet集合实现字符串按照长度进行排序
 * Comparator接口实现定制比较
 */
public class Demo07 {
    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.length()-o2.length();
                int n2 = o1.compareTo(o2);
                return n1==0?n2:n1;
            }
        });
        //添加数据
        treeSet.add("helloworld");
        treeSet.add("pingguo");
        treeSet.add("lisi");
        treeSet.add("zhangsan");
        treeSet.add("cat");
        treeSet.add("nanjing");
        treeSet.add("xian");
        System.out.println(treeSet.toString());

    }
}

六、 Map接口与实现类

Map集合

在这里插入图片描述

Map父接口

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

  • 方法:

    • V put(K key, V value)//将对象存到集合中,关联键值.key重复则覆盖原值。
    • Object get(Object key)//根据键获得对应的值.
    • Set<K> //返回所有Key.
    • Collection<V> values() //返回包含所有值的Collection集合.
    • Set<Map.Entry<K, V>>// 键值匹配的Set集合.
package map;

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

/*
Map接口的使用
特点:1.存储键值对 2.键不能重复,值可以重复 3.无序
 */
public class Demo01 {
    public static void main(String[] args) {
        //创建Map集合
        HashMap<String, String > map = new HashMap<>();
        //1.添加元素
        map.put("cn","中国");
        map.put("uk","英国");
        map.put("usa","美国");
        map.put("cn","zhongguo");//不会添加新的key,但是被新的value给替换掉了。

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

        //2.删除
        /*map.remove("usa");
        System.out.println("删除之后:"+map.size());*/

        //3.遍历
        //3.1使用keyset();
        System.out.println("========================================");
        Set<String > keyset = map.keySet();
        for (String key : keyset) {
            System.out.println(key+"---"+map.get(key));
        }
        //3.2使用entrySet()方法
        System.out.println("========================================");
        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("========================================");
        System.out.println(map.containsKey("cn"));
        System.out.println(map.containsValue("泰国"));

    }
}

在这里插入图片描述

Map集合的实现类

  • HashMap(重点):

    • JDk1.2版本,线程不安全,运行速度快;允许用null作为key或是value。
  • Hashtable:

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

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

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

HashMap的使用

package map;

import java.util.Objects;

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

    public Student() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getStuNo() {
        return stuNo;
    }

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

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return stuNo == student.stuNo &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, stuNo);
    }

    @Override
    //这里比的是学号
    public int compareTo(Student o) {
        int n1 = this.stuNo-o.getStuNo();
        return n1;
    }
}

package 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 >();
        //刚创建hashmap之后没有添加元素 table=null,size=0.  目的是节省空间。
        //添加元素
        Student s1 = new Student("孙悟空",100);
        Student s2 = new Student("猪八戒",101);
        Student s3 = new Student("沙和尚",102);
        students.put(s1,"北京");
        students.put(s2,"上海");
        //students.put(s2,"北京");
        students.put(s3,"杭州");
        //students.put(s3,"南京");
        students.put(new Student("沙和尚",102),"杭州");//需要重写equals和hashcode方法才添加不进去,否则他们添加的地址不同,可以添加。
        System.out.println("元素个数:"+students.size());
        System.out.println(students.toString());

        //2.删除
        /*students.remove(s1);
        System.out.println("删除之后:"+students.size());*/

        //3.遍历
        //3.1 使用keySet();
        System.out.println("====================================================");
        for (Student key : students.keySet()) {
            System.out.println(key.toString()+"---"+students.get(key));
        }
        //3.2使用entrySet();
        System.out.println("====================================================");
        for (Map.Entry<Student, String> entry : students.entrySet()) {
            System.out.println(entry.getKey()+"---"+entry.getValue());
        }

        //4.判断
        System.out.println("====================================================");
        System.out.println(students.containsKey(new Student("孙悟空",100)));
        System.out.println(students.containsValue("杭州"));

    }
}

HashMap源码分析

1.static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // hasMap初始容量大小
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;//元素个数


总结:
    1.HashMap刚创建时,table时null,为了节省空间,当添加第一个元素时,table容量调整为162.当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍,目的是减少调整元素的个数。
    3.jdk1.8 当每个链表长度大于8,并且元素个数大于等于64时,会调整为红黑树,目的是提高执行效率。
    4.jdk1.8 当链表长度小于6时,调整成链表。
    5.jdk1.8以前,链表是头插入,jdk1.8以后是尾插入。
    
    
HashSet源码分析:HashSet的存储结构就是HashMap,它的add方法调用的就是map的put方法,把元素作为map的key传进去的。 

TreeMap的使用

package map;

import java.util.Map;
import java.util.TreeMap;

/*
TreeMap的使用
存储结构:红黑树
和TreeSet区别:TreeSet用的是map的key值。
 */
public class Demo03 {
    public static void main(String[] args) {
        //创建集合(也可以定制比较)
        TreeMap<Student, String > treemap = new TreeMap<Student, String>();
        //1.添加元素
        Student s1 = new Student("孙悟空",100);
        Student s2 = new Student("猪八戒",101);
        Student s3 = new Student("沙和尚",102);
        treemap.put(s1,"北京");
        treemap.put(s2,"上海");
        treemap.put(s3,"深圳");
        treemap.put(new Student("沙和尚",102),"南京");//这里比的是学号,加不进去,但value值可以替换
        System.out.println("元素个数:"+treemap.size());
        //这里必须重写compareTo方法,否则会异常
        System.out.println(treemap.toString());

        //2.删除
        /*treemap.remove(new Student("猪八戒",101),"上海");
        System.out.println(treemap.size());*/

        //3.遍历
        //3.1使用keySet();
        System.out.println("======================================");
        for (Student key : treemap.keySet()) {
            System.out.println(key+"---"+treemap.get(key));
        }
        //3.2 使用entrySet();
        System.out.println("======================================");
        for (Map.Entry<Student, String> entry : treemap.entrySet()) {
            System.out.println(entry.getKey()+"---"+entry.getValue());
        }

        //4.判断
        System.out.println("======================================");
        System.out.println(treemap.containsKey(new Student("沙和尚",102)));

    }
}

七、Collections工具类

  • 概念:集合工具类,定义了除了存取以外的集合常用方法。
  • 方法:
    • public static void reverse(List<?> list)//反转集合中元素的顺序.
    • public static void shuffle(List<?> list)//随机重置集合元素的顺序.
    • public static void sort(List<T> list)//升序排序(元素类型必须实现Comparable接口).
package map;

import java.util.*;

/*
演示Collections工具类的使用
 */
public class Demo04 {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(20);
        list.add(5);
        list.add(12);
        list.add(30);
        list.add(6);
        //sort排序
        System.out.println("排序之前:"+list.toString());
        Collections.sort(list);
        System.out.println("排序之后:"+list.toString());

        //binarySearch二分查找
        int i = Collections.binarySearch(list,13);//有的话输出位置,没有的话输出负数。
        System.out.println(i);

        //copy复制
        ArrayList<Integer> dest = new ArrayList<>();
        //要保证两个数组的长度一样,否则会异常。比如用一个for循环
        for (int k = 0; k <list.size() ; k++) {
            dest.add(0);
        }
        Collections.copy(dest,list);
        System.out.println(dest.toString());

        //reverse反转
        Collections.reverse(list);
        System.out.println("反转之后:"+list);

        //shuffle打乱
        Collections.shuffle(list);
        System.out.println("打乱之后:"+list);


        //补充:list转成数组
        System.out.println("===============================================");
        Integer[] arr = list.toArray(new Integer[0]);//这个数比长度打的话会多余部分显示null.
        System.out.println(arr.length);
        System.out.println(Arrays.toString(arr));

        //数组转成集合
        System.out.println("===============================================");
        String[] names = {"张三","李四","王五"};
        //集合是一个受限集合,不能添加和删除
        List<String> list2 = Arrays.asList(names);
        //list2.add("赵六");
        //list2.remove(0);
        System.out.println(list2);
        //把基本类型数组转成集合时,需要修改为包装类型。
        Integer[] nums = {100,200,300,400,500};
        List<Integer> list3 = Arrays.asList(nums);
        System.out.println(list3);




    }
}

八、总结

  • 集合的概念:

    • 对象的容器,存储对象的对象,定义了对多个对象进行操作的常用方法。
  • List集合:

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

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

    • 存储一对数据,键不可重复,值可里复。(HasnMap、HashTable、Properties、TreeMap)。
  • Collections:

    • 集合工具类,定义了除了存取以外的集合常用方法。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值