java集合框架详解

1. 什么是集合?

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

和数组的区别:

  1. 数组长度固定,集合长度不固定
  2. 数组可以存储基本类型和引用类型,集合只能存储引用类型

位置: java.util.*

2. Collection 体系集合

在这里插入图片描述

2.1 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()//将此集合转换成数组。
iterator():对此集合的元素进行遍历。

2.2 Collection使用

使用字符串作为元素

package commonClass.stringClass;

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

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

public class TestCollection {
    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. 删除元素
//        collection.remove("榴莲");
//        System.out.println("删除之后" + collection.size());
//        collection.clear();
//        System.out.println("清空之后" + collection.size());
        //    3. 遍历元素
        // 3.1 使用增强for
        System.out.println("===============使用增强for================");
        for (Object o : collection) {
            System.out.println(o);
        }
        // 3.2 使用迭代器(迭代器专门用来遍历集合的一种方式)
        System.out.println("===============使用迭代器================");
        // 有三个方法:
        // hasNext(); 有没有下一个元素          (迭代时先执行)
        // next(); 获取下一个元素
        // remove(); 删除当前元素
        Iterator it  = collection.iterator(); // 返回类型是接口类型的
        while (it.hasNext()){
            String s = (String) it.next();
            System.out.println(s);
              //collection.remove(s); // 迭代过程中 不能使用collection删除方法, 但是可以用 it.remove();
            //it.remove();
        }
        System.out.println("元素个数" + collection.size());
        //   4. 判断
        System.out.println(collection.contains("西瓜"));
        System.out.println(collection.isEmpty());
    }
}

使用类对象作为元素

package commonClass.stringClass;

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

/**
 * 保存学生信息
 */
public class TestCollection02 {
    public static void main(String[] args) {
        // 新建collection对象
        Collection collection =  new ArrayList();
        Student s1 = new Student("张三",10);
        Student s2 = new Student("张无忌",28);
        Student s3 = new Student("李四",50);
        // 1. 添加数组
        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        collection.add(s3);
        System.out.println("元素个数: "+ collection.size());
        System.out.println(collection.toString());
        // 2. 删除, 只是把集合中的地址删除了
        //collection.remove(s3);
        //collection.remove(new Student("李四",50)); 不能这样做,remove用的是equals比较
        //collection.clear();
        System.out.println("删除之后: "+ collection.size());
        System.out.println(collection.toString());
        // 3. 遍历
        // 3.1 增强for
        for (Object o : collection) {
            Student s = (Student)o;
            System.out.println(s.toString());
        }
        // 3.2 迭代器 hasNext() next() remove() ; 迭代过程中不能使用collection的删除方法
        Iterator it = collection.iterator();
        while (it.hasNext()){
            Student s = (Student) it.next();
            System.out.println(s.toString());
        }
        //  4.  判断
        System.out.println(collection.contains(s1));
        System.out.println(collection.isEmpty());
    }
}

3. List集合

3.1 List子接口

特点: 有序,有下表,元素可以重复
方法:

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

3.2 List接口使用1

package commonClass.stringClass;

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

/**
 * List子接口的使用
 * 特点:  有序,有下表,可以重复
 */
public class TestList {
    public static void main(String[] args) {
        // 创建集合对象
        List list = new ArrayList<>();
        // 1. 添加元素
        list.add("苹果");
        list.add("小米");
        list.add(0,"华为");
        System.out.println("元素个数:" + list.size());
        System.out.println(list.toString());
        //2. 删除元素;
//        list.remove(0);
//        list.remove("苹果");
//        System.out.println("删除后:" + list.size());
//        System.out.println(list.toString());
        // 3. 遍历
        // 3.1  使用for进行遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        // 3.2 使用增强for
        for (Object o : list) {
            System.out.println(o);
        }
        // 3.3 使用迭代器
        Iterator it = list.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        // 3.4 使用列表迭代器, 和Iterator的区别 ListIterator可以向前向后遍历,添加,删除,修改元素
        ListIterator lit = list.listIterator();
        System.out.println("==============================3.4 使用列表迭代器,从前往后===================");
        while (lit.hasNext()){
            System.out.println(lit.nextIndex()+":"+lit.next());
        }
        System.out.println("==============================3.4 使用列表迭代器,从后往前===================");
        while (lit.hasPrevious()){
            System.out.println(lit.previousIndex()+":"+lit.previous());
        }
        // 4. 判断
        System.out.println(list.contains("苹果"));
        System.out.println(list.isEmpty());
        // 5. 获取
        System.out.println(list.indexOf("华为"));
    }
}

3.3 List使用接口2

package commonClass.stringClass;

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

public class TestList02 {
    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);
        list.add(200);
        System.out.println("元素个数:"+ list.size());
        System.out.println(list.toString());
        // 2. 删除操作
        //list.remove(0);
        //list.remove((Object) 20);
        list.remove(new Integer(200));
        System.out.println("删除元素:"+ list.size());
        System.out.println(list.toString());
        // 3. 补充方法 subList: 返回子集合; 含头不含尾
        List subList = list.subList(1,3);
        System.out.println(subList.toString());

    }
}

4. List实现类

ArraysList【重点】:

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

Vector:

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

LinkedList:

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

4.1 ArrayList使用

package commonClass.ArrayListDemo;

import commonClass.stringClass.Student;

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

/**
 * ArrayList的使用
 * 存储结构: 数组,查找遍历快,增删慢
 */
public class ArrayListDemo {
    public static void main(String[] args) {
        // 创建集合
        ArrayList arrayList = new ArrayList();
        // 1. 添加元素
        Student s1 = new Student("刘德华",20);
        Student s2 = new Student("周杰论",25);
        Student s3 = new Student("梁朝伟",56);
        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));
        System.out.println("元素个数:" + arrayList.size());
        // 重写类的equals方法
//        @Override
//        public boolean equals(Object o) {
//            // 判断是不是同一对象
//            if(this == o){
//                return true;
//            }
//            if(o == null){  // 判断是否为空
//                return false;
//            }
//            // 判断是否是student类型
//            if(o instanceof Student){
//                Student s = (Student) o;
//                // 比较属性
//                if(this.name.equals(s.getName()) && this.age == s.getAge()){
//                    return true;
//                }
//            }
//            // 不满足返回false
//            return false;
//        }
        // 3. 遍历元素
        // 3.1 使用迭代器
        Iterator iterator = arrayList.iterator();
        while (iterator.hasNext()){
            Student s = (Student) iterator.next();
            System.out.println(s.toString());
        }
        // 3.2 列表迭代器
        ListIterator lit = arrayList.listIterator();
        while (lit.hasNext()) {
            System.out.println(lit.next().toString());
        }
        // 逆序
        while(lit.hasPrevious()){
            Student s = (Student) lit.previous();
            System.out.println(s.toString());
        }
        // 4. 判断
        System.out.println(arrayList.contains(s2));
        System.out.println(arrayList.contains(new Student("刘德华",20)));
        System.out.println(arrayList.isEmpty());
        // 5. 查找
        System.out.println(arrayList.indexOf(s3));
    }

}

重写toString和equals方法

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

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

4.2 ArrayList源码分析

默认容量大小为10
注意:如果没有向集合中添加任何元素,容量为0

    /**
     * Default initial capacity.
     */
    private static final int DEFAULT_CAPACITY = 10;

elementData,存放元素的数组


    /**
     * The array buffer into which the elements of the ArrayList are stored.
     * The capacity of the ArrayList is the length of this array buffer. Any
     * empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
     * will be expanded to DEFAULT_CAPACITY when the first element is added.
     */
    transient Object[] elementData; // non-private to simplify nested class access

实际的元素个数


    /**
     * The size of the ArrayList (the number of elements it contains).
     *
     * @serial
     */
    private int size;

add添加元素,添加一个任意元素之后,容量10。扩容是原来的1.5倍


    /**
     * Appends the specified element to the end of this list.
     *
     * @param e element to be appended to this list
     * @return {@code true} (as specified by {@link Collection#add})
     */
    public boolean add(E e) {
        modCount++;
        add(e, elementData, size);
        return true;
    }

4.3 Vector类使用

数组结构,查询类、增删慢;

package commonClass.ArrayListDemo;

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

/**
 * 演示vector集合的使用
 * 存储结构: 数组
 */
public class VectorTest {
    public static void main(String[] args) {
        // 创建集合
        Vector vector = new Vector();
        vector.add("草莓");
        vector.add("苹果");
        vector.add("西瓜");
        vector.add("梨");
        System.out.println("元素个数"+ vector.size());
        System.out.println(vector.toString());
        // 2. 删除
//        vector.remove(0);
//        vector.remove("西瓜");
//        vector.clear();
        // 2. 遍历
        // 使用枚举器
        Enumeration en = vector.elements();
        while (en.hasMoreElements()){
            String o = (String) en.nextElement();
            System.out.println(o);
        }
        // 4. 判断
        System.out.println(vector.contains("西瓜"));
        // 5. vector其他方法
        // fitstElement, lastElement, elementAt();




    }
}

4.4 LinkedList使用*

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

package commonClass.ArrayListDemo;

import commonClass.stringClass.Student;

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

/**
 * LinkedList的使用
 * 存储结构: 双向链表
 */
public class LinkedListTest {
    public static void main(String[] args) {
        // 创建集合
        LinkedList linkedList = new LinkedList();
        // 1. 添加元素
        Student s1 = new Student("刘德华",20);
        Student s2 = new Student("周杰论",25);
        Student s3 = new Student("梁朝伟",56);
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        linkedList.add(s3);
        System.out.println("元素个数: " + linkedList.size());
        System.out.println(linkedList.toString());
        System.out.println(linkedList);
        // 2. 删除元素
//        linkedList.remove(s1);
//        linkedList.remove(new Student("刘德华",20));
//        System.out.println("元素个数: " + linkedList.size());
        // 3. 遍历
        // 3.1 for
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
        // 3.2 增强for
        for (Object o : linkedList) {
            Student s = (Student)o;  //强制类型转换,因为放进去后 就变成object类型了
            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());
        }
        System.out.println("====================列表迭代器");
        ListIterator lit = linkedList.listIterator();
        while (lit.hasNext()){
            Student s = (Student)lit.next();
            System.out.println(s );
        }
        // 4判断
        System.out.println(linkedList.contains(s1));
        System.out.println(linkedList.isEmpty());
        // 5 获取
        System.out.println(linkedList.indexOf(s1));

    }
}

4.5 LinkedList源码分析

在这里插入图片描述

item 实际数据
next 下一个节点
prev 前一个节点


在这里插入图片描述

4.6 ArrayList和LinkedList区别

在这里插入图片描述

5. 泛型

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

5.1 泛型类

package commonClass.MyGeneric;

public class TestGeneric {
    public static void main(String[] args) {
        //使用泛型类来创建对象
        // 注意 1 泛型只能使用引用类型  2. 不同泛型对象之间不能相互复制
        MyGeneric<String > myGeneric = new MyGeneric<String>();
        myGeneric.t = "hello";
        myGeneric.show("大家好!!");
        String t = myGeneric.getT();
        
        MyGeneric<Integer> myGeneric1 = new MyGeneric<Integer>();
        myGeneric1.t = 100;
        myGeneric1.show(200);
        Integer integer = myGeneric1.getT();

    }
}

package commonClass.MyGeneric;

/**
 * 泛型类
 * 语法: 类名<T,E>
 *     T类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
 */
public class MyGeneric<T> {
    // 使用泛型T
    // 1. 创建变量
    T t ;
    // 2. 添加一个方法,作为方法的参数
    public void show(T t){
        // 不能new对象,实例化。
        System.out.println(t);
    }
    // 3. 泛型作为方法的返回值
    public T getT(){
        return t;
    }

}

5.2 泛型接口

实现类时确实类型

package commonClass.MyGeneric;

public class MyInterfacempl implements MyInterface<String>{  // 实现接口,泛型类要具体


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

实现类时不确实类型

package commonClass.MyGeneric;
// 实现接口时不确定
public class MyInterfaceImpl2<T> implements MyInterface<T>{
    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}

测试

package commonClass.MyGeneric;

public class TestGeneric {
    public static void main(String[] args) {
        System.out.println("===================================");
        MyInterfacempl impl = new MyInterfacempl();
        impl.server("xxxxxxxxxxxxxxxx");

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

    }
}

5.3 泛型方法

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

public class TestGeneric {
    public static void main(String[] args) {
        // 泛型方法调用
        MyGenericMethod myGenericMethod = new MyGenericMethod();
        myGenericMethod.show("string hahaha ni shi shui wo sh");
        myGenericMethod.show(200);
        myGenericMethod.show(3.14);
    }
}

5.4 泛型集合

·概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致。
·特点:
·编译时即可检查,而非运行时抛出异常。
·访问时,不必类型转换(拆箱)。
·不同泛型之间引用不能相互赋值,泛型不存在多态。

package commonClass.MyGeneric;

import commonClass.stringClass.Student;
import oop.demo08.A;

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

public class Demo3 {
    public static void main(String[] args) {
        ArrayList<String>  arrayList = new ArrayList<String>();
        arrayList.add("xxx");
        arrayList.add("xxx");
//        arrayList.add(10);
        for (String s : arrayList) {
            System.out.println(s);
        }
        ArrayList<Student> arrayList1 = new ArrayList<>();
        commonClass.stringClass.Student s1 = new commonClass.stringClass.Student("刘德华",20);
        commonClass.stringClass.Student s2 = new commonClass.stringClass.Student("周杰论",25);
        commonClass.stringClass.Student s3 = new commonClass.stringClass.Student("梁朝伟",56);
        arrayList1.add(s1);
        arrayList1.add(s2);
        arrayList1.add(s1);
        arrayList1.add(s1);
        Iterator<Student> it = arrayList1.iterator();
        while (it.hasNext()){
            Student s = it.next();
            System.out.println(s.toString());
        }
    }
}

6. Set集合

Set子接口: 无序、无下标、元素不可重复。

package commonClass.MySet;

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

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

6.1 HashSet使用

·HashSet【重点】:
·基于HashCode计算元素存放位置。
·当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。

package commonClass.MySet;

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

/**
 * HashSet的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 */
public class MyHashSet {
    public static void main(String[] args) {
        // 新建集合
        HashSet<String> hashSet = new HashSet<>();
        // 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.toString());
        // 3. 遍历
        System.out.println("==================增强for");
        for (String s : hashSet) {
            System.out.println(s);
        }
        System.out.println("==================Iterator");
        Iterator<String> it = hashSet.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        // 4. 判断
        System.out.println(hashSet.contains("郭富城"));
        System.out.println(hashSet.isEmpty());

    }
}

6.2 HashSet使用(2)

package commonClass.MySet;

import java.util.HashSet;

public class MyHashSet02 {
    public static void main(String[] args) {
        // 创建集合
        HashSet<Person> persons = new HashSet<>();
        // 1. 添加数据
        Person p1 = new Person("刘德华“", 50);
        Person p2 = new Person("周润发“", 501);
        Person p3 = new Person("周杰林“", 22);
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(new Person("周杰林“", 22));
        System.out.println("元素个数:" + persons.size());
        System.out.println(persons.toString());
         // 2. 删除操作
        persons.remove(p1);
        persons.remove(new Person("周杰林“", 22));
        System.out.println("删除之后:" + persons.size());

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

        // 4. 判断
        System.out.println(persons.contains(p1));
        System.out.println(persons.isEmpty());
    }
}

6.3 HashSet存储方式

存储过程:

  1. 根据hashcode,计算保存的位置;如果此位置为空,则直接保存,若不为空,执行第二步。
  2. 再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
    在这里插入图片描述
    person,重写了hashcode和equals方法
package commonClass.MySet;

import java.util.Objects;

/**
 * 人类
 */
public class Person {
    private String name;
    private int age;

    public Person() {
    }

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

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null ) return false;
        if( o  instanceof Person){
            Person person = (Person) o;
            if(this.name.equals(person.getName()) && this.age == person.getAge()){
                return true;
            }
        }

        return false;
    }

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

6.4 HashSet补充

31
(1)31是一个质数,减少散列冲突
(2)31能够提高执行效率 31*i = (i<<5)-i

    public static int hashCode(Object a[]) {
        if (a == null)
            return 0;

        int result = 1;

        for (Object element : a)
            result = 31 * result + (element == null ? 0 : element.hashCode());

        return result;
    }

6.5 TreeSet概述

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

6.6 TreeSet的使用

package commonClass.MySet;

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

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

        // 2. 删除元素
        treeSet.remove("xyz");
        System.out.println("打印元素个数:" + treeSet.size());
        System.out.println(treeSet.toString());
        // 3. 遍历
        // 3.1 增强for
        for (String s : treeSet) {
            System.out.println(s);
        }
        // 3.2 iter
        Iterator it = treeSet.iterator();
        while (it.hasNext()){
            System.out.println(it.next());
        }
        // 4. 判断
        System.out.println(treeSet.contains("abd"));
    }

}

不能正常添加元素。因为TreeSet要求根据某一指标的数值大小才能存放数据。
因为类没有标准,得告诉treeset怎么比
在这里插入图片描述
在person类中,实现Comparable接口,重写比较方法,

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


    // 先按姓名来比,然后按年龄比
    @Override
    public int compareTo(Person o) {
        int n1 = this.getName().compareTo(o.getName());//字符串有comparaTo方法的
        int n2 = this.age-o.getAge();
        return n1 == 0 ? n2 : n1;
    }

package commonClass.MySet;

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

/**
 * 使用TreeSet保存数据
 * 要求: 元素必须要实现Comparable类,compareTo()方法返回值为0,认为是重复元素
 */
public class MyTreeSet02 {
    public static void main(String[] args) {
        // 创建集合
        TreeSet<Person> person = new TreeSet<>();
        // 1. 添加元素
        Person p1 = new Person("刘德华", 20);
        Person p2 = new Person("周杰伦", 23);
        Person p3 = new Person("王祖蓝", 24);
        person.add(p1);
        person.add(p2);
        person.add(p3);
        System.out.println("元素个数: " + person.size());
        System.out.println(person.toString());
        // 2. 删除
        person.remove(p1);
        person.remove(new Person("王祖蓝", 24)); // 实现了compara接口,所以能删除
        System.out.println("元素个数: " + person.size());
        // 3. 遍历
        // 3.1 增强for
        for (Person person1 : person) {
            System.out.println(person1);
        }
        // 3.2 迭代器
        Iterator<Person> ite = person.iterator();
        while (ite.hasNext()){
            System.out.println(ite.next());
        }
        // 4. 判断
        System.out.println(person.contains(p1));

    }
}


6.7 Comparator接口

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

package commonClass.MySet;

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

/**
 * TreeSet集合的使用
 * Comparator: 实现定制比较(比较器)
 * Comparable: 可比较的
 */
public class MyTreeSet03 {
    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;
            }
        });
        // 1. 添加元素
        Person p1 = new Person("x", 20);
        Person p2 = new Person("t", 23);
        Person p3 = new Person("a", 24);
        Person p4 = new Person("b", 24);
        persons.add(p1);
        persons.add(p2);
        persons.add(p3);
        persons.add(p4);
        System.out.println(persons.toString());

    }
}

6.8 TreeSet案例

package commonClass.MySet;

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

/**
 * 使用Treeset集合 实现字符串按照长度进行排序
 *
 */
public class MyTreeSet04 {
    public static void main(String[] args) {
        // 创建集合并指定比较规则,  treeset不需要重写equals和hashcode
        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("hello");
        treeSet.add("hell");
        treeSet.add("hel");
        treeSet.add("ho");
        treeSet.add("zhangsan");
        treeSet.add("cat");
        treeSet.add("nanjing");
        System.out.println(treeSet.toString());
        System.out.println("元素个数:"+ treeSet.size());
    }
}

7. Map集合概述

在这里插入图片描述
·特点:存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复。
·方法:
V put(K key,V value) 将对象存入到集合中,关联键值。key重复则覆盖原值。
Object get(Object key) 根据键获取对应的值。
Set<K> keySet(); 返回所有key。
Collection<V> values() 返回包含所有值的Collection集合。
Set<Map.Entry<K,V>> 键值匹配的Set集合。

7.1 Map接口使用

package commonClass.MyMap;

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

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

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

        // 2. 删除
        map.remove("usa");
        System.out.println(map.toString());
         // 3. 遍历
        // 3.1 使用keySet()   返回值是所有key的set集合
        Set<String> keyset = map.keySet();
        for (String s : keyset) {
            System.out.println(s  +  "-----------" + map.get(s));
        }
        for (String s : map.keySet()) {
            System.out.println(s  +  "-----------" + map.get(s));
        }
        // 3.2 使用entrySet()方法
        Set<Map.Entry<String ,String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            System.out.println(entry.getKey()+"------------" + entry.getValue());
        }
        for (Map.Entry<String, String> entry : map.entrySet()) {
            System.out.println(entry.getKey()+"------------" + entry.getValue());
        }
                // 4. 判断
        System.out.println(map.containsKey("cn"));
        System.out.println(map.containsValue("cn"));
    }
}

在这里插入图片描述

7.2 HashMap的使用

HashMap【重点】:
JDK1.2版本,线程不安全,运行效率快;允许用nul1作为key或是value。

package commonClass.MyMap;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.PatternSyntaxException;

/**
 * HashMap的使用
 * 存储结构:哈希表(数值+ 链表 + 红黑树)
 * 使用key的hashcode和equals作为重复
 */
public class MyHashMap {
    public static void main(String[] args) {
        // 创建集合
        HashMap<Student,String> students = new HashMap<>();
        // 刚创建Mashmap之后,没有添加元素 table = null, size= 0
        //  目的节省空间
        // 添加元素
        Student s1 = new Student("孙悟空",100);
        Student s2 = new Student("猪八戒",101);
        Student s3 = new Student("沙僧",103);
        students.put(s1,"北京");
        students.put(s2,"上海");
        students.put(s3,"东海");
        students.put(s3,"南京");
        students.put(new Student("沙僧",103),"南京");  // 重写hashcode和equals方法,就可以添加进来
        System.out.println("元素个数:" + students.size());
        System.out.println(students.toString());
        // 2. 删除
        students.remove(s1);
        System.out.println("删除之后:" + students.size());
        // 3. 遍历
        // 3.1 使用keySet();
        for (Student student : students.keySet()) {
            System.out.println(student.toString() + "---" + students.get(student));
        }
        // 3.2 使用entrySet();
        for (Map.Entry<Student, String> entry : students.entrySet()) {
            System.out.println(entry.getKey()+ "======" + entry.getValue());
        }
        // 4. 判断
        System.out.println(students.containsKey(s1));
        System.out.println(students.containsKey(new Student("沙僧",103)));
    }
}

package commonClass.MyMap;

import java.util.Objects;

public class 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);
    }
}

7.3 HashMap源码分析

jdk 1.8
当链表长度大于8,并且这个数组的长度大于64,就会把链表调整为红黑树。

刚创建Mashmap之后,没有添加元素 table = null, size= 0


    /**
     * The bin count threshold for using a tree rather than list for a
     * bin.  Bins are converted to trees when adding an element to a
     * bin with at least this many nodes. The value must be greater
     * than 2 and should be at least 8 to mesh with assumptions in
     * tree removal about conversion back to plain bins upon
     * shrinkage.
     */
    static final int TREEIFY_THRESHOLD = 8;

在这里插入图片描述
当添加第一个元素时,数组容量为16

在这里插入图片描述

(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以后时是尾插入

7.4 Hashtable和Properies

在这里插入图片描述

7.5 TreeMap的使用

在这里插入图片描述

package commonClass.MyMap;

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

/**
 * TreeMap的使用
 * 存储结构: 红黑树
 */
public class MyTreeMap {
    public static void main(String[] args) {
        // 新建集合(定制比较)
        TreeMap<Student, String> treeMap = new TreeMap<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return 0;
            }
        });
        // 1. 添加元素
        Student s1 = new Student("孙悟空",100);
        Student s2 = new Student("猪八戒",101);
        Student s3 = new Student("沙僧",103);
        treeMap.put(s1, "北京");
        treeMap.put(s2, "上海");
        treeMap.put(s3, "南京");
        treeMap.put(new Student("沙僧",103), "南京");
        System.out.println(treeMap.size());
        System.out.println(treeMap.toString());

        // 2. 删除
        treeMap.remove(s3);
        System.out.println(treeMap.toString());
        
        // 3. 遍历
        // 3.1 使用keySet
        for (Student student : treeMap.keySet()) {
            System.out.println(student + "=======" + treeMap.get(student));
            
        }
        // 3.2 使用entryset
        for (Map.Entry<Student, String> studentStringEntry : treeMap.entrySet()) {
            System.out.println(studentStringEntry.getKey()+studentStringEntry.getValue());
        }
        // 4. 判断
        System.out.println(treeMap.containsKey(s1));
    }
}

8. Collections工具类

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

package commonClass.MyMap;

import java.util.*;

public class MyCollection {
    public static void main(String[] args) {
        List<Integer>  list = new ArrayList<>();
        list.add(20);
        list.add(10);
        list.add(30);
        list.add(2);
        list.add(6);
        // sort 排序
        System.out.println(list.toString());
        Collections.sort(list);
        System.out.println(list.toString());
        Collections.sort(list);
        // binarySearch 二分查找
        int a = Collections.binarySearch(list,12);
        int b = Collections.binarySearch(list,20);
        System.out.println(a);
        System.out.println(b);
        // copy 复制
        List<Integer> dest = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            dest.add(0);
        }
        Collections.copy(dest, list);
        System.out.println(dest.toString());

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

        // shuffle 打乱
        Collections.shuffle(list);
        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));
        // 数组转成集合
        System.out.println("==========数组转成集合============");
        String[] name = {"张三","李四","王五"};
        List<String> list2 = Arrays.asList(name);
        // 集合是受限集合,不能添加和删除
        System.out.println(list2.toString());
        System.out.println(list2);

        // 把基本类型数组 转成集合时, 需要修改为包装类
//        int[] nums = {54,123,564,6,132,132,56,4,3,4,6};
//        List<int[]> list3 = Arrays.asList(nums);
        Integer[] nums = {54,123,564,6,132,132,56,4,3,4,6};
        List<Integer> list3 = Arrays.asList(nums);
        System.out.println(list3);


    }
}

8 .总结

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值