Java集合框架

集合

◆ 集合的概念:什么是集合?

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

◆ 和数组的区别:

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

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

◆ 位置

Java.util.*(所有的类都在这个包里面)

Collection体系集合

◆ Collection父接口

特点:代表一组任意类型对象,无序、无下标、不能重复

方法:(列出一些)

  1. boolean add(Object obj); //添加一个对象

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

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

  4. boolean contains(Object o); //检查此集合中是否包含o对象

  5. boolean equals(Object o); //比较此集合是否与指定对象相等

  6. boolean isEmpty(); //判断此集合是否为空

  7. Iterator<E> iterator(); //返回在此集合的元素上进行迭代的迭代器(专门用来遍历集合的一种方式)

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

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

  10. Object[] toArray(); //将此集合转成数组

List子接口

◆ 特点:

有序、有下标、元素可以重复

◆ 方法:(列出一些)

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

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

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

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

List实现类

ArrayList

◆ ArrayList【重点】:

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

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

  3. 源码分析:

    1)默认容量大小:int DEFAULT_CAPACITY = 10

    注意:如果没有向集合中添加任何元素时,容量为0,添加一个元素之后,容量为10,填满之后就扩容(每次扩容,大小都为原来的1.5倍)

    2)存放元素的数组:Object[] elementData

    3)实际元素个数:int size

    4)添加元素:add();

public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
}
​
private void ensureCapacityInternal(int minCapacity) {
        ensureExplicitCapacity(calculateCapacity(elementData, 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);
}
/**
 * ArrayList的使用
 * 存储结构:数组,查找遍历速度快,增删慢
 */
public class ListArrayList {
    public static void main(String[] args) {
        //创建集合  size 0 容量 0,扩容(每次扩容,大小都为原来的1.5倍)
        ArrayList arrayList = new ArrayList<>();
        //1. 添加元素
        Student02 s1 = new Student02("刘德华",21);
        Student02 s2 = new Student02("郭富城",20);
        Student02 s3 = new Student02("黎明",25);
        Student02 s4 = new Student02("张学友",23);
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        arrayList.add(s4);
        System.out.println("元素个数:"+arrayList.size());
        System.out.println(arrayList);
​
        //2. 删除元素
        //arrayList.remove(s1);
        //删除时,想要通过new一个对象删除,就必须要重写equals();方法,因为new一个对象删除实际上是用了equals();方法
//        arrayList.remove(new Student02("刘德华",21)); //equals(this==obj)
//        System.out.println("删除之后:"+arrayList.size());
//        System.out.println(arrayList);
​
        //3. 遍历元素
        //3.1 迭代器
        System.out.println("----------使用迭代器-------------");
        Iterator it = arrayList.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        //3.2 列表迭代器
        System.out.println("----------使用列表迭代器从前往后-------------");
        ListIterator lit= arrayList.listIterator();
        while (lit.hasNext()) {
            Student02 s = (Student02) lit.next();
            System.out.println(s);
        }
        System.out.println("----------使用列表迭代器从后往前-------------");
        while (lit.hasPrevious()) {
            System.out.println(lit.previous());
        }
​
        //4. 判断 contains(Object o);判断集合里有没有o对象
        System.out.println(arrayList.contains(s1));
        //这时候已经重写了equals();方法
        System.out.println(arrayList.contains(new Student02("刘德华",21)));
        //5. 查找
        System.out.println(arrayList.indexOf(new Student02("刘德华",21)));
    }
}
public class Student02 {
    private String name;
    private int age;
​
    public Student02(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 "Student02{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
​
    @Override
    public boolean equals(Object obj) {
        //1.判断是否是同一个对象
        if (this==obj) {
            return true;
        }
        //2.判断是否为空
        if (obj==null) {
            return false;
        }
        //3.判断是否是Student02类
        if (obj instanceof Student02) {
            Student02 s = (Student02) obj;
            //4.比较属性
            if (this.name.equals(s.getName())&&this.age==s.getAge()) {
                return true;
            }
        }
        //5.不满足条件返回false
        return false;
    }
}

Vector

◆ Vector(现在的开发用的不是特别多):

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

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

/**
 * Vector的使用
 * 存储结构:数组
 * 查询快、增删慢
 */
public class ListVector {
    public static void main(String[] args) {
        //创建集合
        Vector vector = new Vector<>();
        //1. 添加元素
        vector.add("草莓");
        vector.add("木瓜");
        vector.add("芒果");
        vector.add("西瓜");
        System.out.println("元素个数:"+vector.size());
        System.out.println(vector);
​
        //2. 删除元素
        //vector.remove(0);
        //vector.remove("木瓜");
        //vector.clear();
//        System.out.println("删除之后:"+vector.size());
//        System.out.println(vector);
​
        //3. 遍历
        //使用枚举器,JDK1.2之前遍历Vector用的是枚举器
        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. 其他的方法
        System.out.println(vector.firstElement());
        System.out.println(vector.lastElement());
        System.out.println(vector.elementAt(2));
​
    }
}

LinkedList

◆ LinkedList:

  1. 链表结构实现(双向链表),增删快、查询慢

  2. 源码分析:

    1)集合的大小:int size

    2)链表的头节点:Node first

    3)链表的尾结点: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;
        }
}
/**
 * LinkedList的使用
 * 存储结构:双向链表
 */
public class ListLinkedList {
    public static void main(String[] args) {
        //创建集合
        LinkedList linkedList = new LinkedList<>();
        //1. 添加元素
        Student02 s1 = new Student02("张三丰",20);
        Student02 s2 = new Student02("令狐冲",22);
        Student02 s3 = new Student02("任我行",25);
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        System.out.println("元素个数:"+linkedList.size());
        System.out.println(linkedList);
​
        //2. 删除元素
        //linkedList.remove(1);
        //linkedList.remove(s1);
//        linkedList.remove(new Student02("张三丰",20));
//        System.out.println("删除之后:"+linkedList.size());
//        System.out.println(linkedList);
​
        //3. 遍历
        //3.1 使用for遍历
        System.out.println("------------使用for遍历-----------");
        for (int i = 0; i < linkedList.size(); i++) {
            System.out.println(linkedList.get(i));
        }
        //3.2 使用增强for
        System.out.println("------------使用增强for-----------");
        for (Object obj : linkedList) {
            Student02 s = (Student02) obj;
            System.out.println(s);
        }
        //3.3 使用迭代器
        System.out.println("------------使用迭代器-----------");
        Iterator it = linkedList.iterator();
        while (it.hasNext()) {
            Student02 s = (Student02) it.next();
            System.out.println(s);
        }
        //3.4 使用列表迭代器
        System.out.println("------------使用列表迭代器从前往后-----------");
        ListIterator lit = linkedList.listIterator();
        while (lit.hasNext()) {
            Student02 s = (Student02) lit.next();
            System.out.println(s);
        }
        System.out.println("------------使用列表迭代器从后往前-----------");
        while (lit.hasPrevious()) {
            Student02 s = (Student02) lit.previous();
            System.out.println(s);
        }
​
        //4. 判断
        System.out.println(linkedList.contains(s1));
        System.out.println(linkedList.isEmpty());
        //5. 获取
        System.out.println(linkedList.indexOf(s2));
    }
}

ArrayList和LinkedList的区别

泛型

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

◆ 常见形式:泛型类、泛型接口、泛型方法

◆ 语法:<T,...> T称为类型占位符,表示一种引用类型

◆ 好处:

1)提高代码的重用性

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

泛型类

/**
 * 泛型类
 * 语法:类名<T>
 *     T是类型占位符,表示一种引用类型,如果编写多个,使用逗号隔开
 */
public class MyGeneric<T> {
    //使用泛型T
    //1.创建变量
    T t;
​
    //2.添加方法
    public void show(T t) {
        //T t1 = new T();  不能直接实例化,不知道T的类型,不保证能传过来的T的类型的构造方法能用,也不能保证传过来的类型一定有无参构造
        System.out.println(t);
    }
​
    //3.使用泛型作为方法的返回值
    public T getT() {
        return t;
    }
}
​
public class MyGenericTest {
    public static void main(String[] args) {
        //使用泛型类创建对象
        //注意:
        //1. 泛型只用使用引用类型
        //2. 不同泛型类型对象之间不能相互复制
        MyGeneric<String> myGeneric = new MyGeneric<>();
        myGeneric.t = "hello";
        myGeneric.show("加油,同学!");
        String str = myGeneric.getT();
        System.out.println(myGeneric.t);
        System.out.println(str);
​
        MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
        myGeneric2.t = 100;
        myGeneric2.show(150);
        Integer integer = myGeneric2.getT();
        System.out.println(myGeneric2.t);
        System.out.println(integer);
​
        //MyGeneric<String> myGeneric3 = myGeneric2;
    }
}

泛型接口

/**
 * 泛型接口
 * 语法:接口名<T>
 * 注意:不能使用泛型创建静态常量
 */
public interface MyInterface<T> {
    String name = "张三";
​
    T server(T t);
}
​
//泛型接口实现类,用之前确定类型,比如此实现类是String类型
public class MyInterfaceImpl implements MyInterface<String>{
    @Override
    public String server(String s) {
        System.out.println(s);
        return s;
    }
}
​
//泛型接口实现类,用的时候确定类型,比如此类还没确定,但是测试类new的时候确定类型
public class MyInterfaceImpl2<T> implements MyInterface<T>{
    @Override
    public T server(T t) {
        System.out.println(t);
        return t;
    }
}
​
public class MyInterfaceImplTest {
    public static void main(String[] args) {
        //用之前确定类似,比如此类为String类
        MyInterfaceImpl impl = new MyInterfaceImpl();
        impl.server("xxxxx");
​
        //用时确定类型,比如此类,用时为Integer类
        MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
        impl2.server(1000);
    }
}

泛型方法

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

public class MyGenericMethodTest {
    public static void main(String[] args) {
        MyGenericMethod myGenericMethod = new MyGenericMethod();
        myGenericMethod.shou("fsd");
        myGenericMethod.shou(200);
        myGenericMethod.shou(3.14);
    }
}

泛型集合

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

◆ 特点:

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

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

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

public class MyGenericJihe {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<>();
        arrayList.add("aaa");
        arrayList.add("bbb");
        arrayList.add("ccc");
        for (String str : arrayList) {
            System.out.println(str);
        }

        ArrayList<Student02> arrayList2 = new ArrayList<>();
        Student02 s1 = new Student02("刘德华",21);
        Student02 s2 = new Student02("郭富城",20);
        Student02 s3 = new Student02("黎明",25);
        Student02 s4 = new Student02("张学友",23);
        arrayList2.add(s1);
        arrayList2.add(s2);
        arrayList2.add(s3);
        arrayList2.add(s4);

        Iterator<Student02> it = arrayList2.iterator();
        while (it.hasNext()) {
            Student02 s = it.next();
            System.out.println(s);
        }
        //arrayList2 = arrayList;  泛型类型不同不能相互赋值
    }
}

Set子接口

◆ 特点:

无序、无下标、元素不可重复

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

Set实现类

HashSet

◆ HashSet【重点】:

  1. 基于HashCode实现元素不重复

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

/**
 * HashSet集合的使用
 * 存储结构:哈希表(数组+链表(HDK1.7之前)+红黑树(JDK1.8之后))
 */
public class Set_HashSet {
    public static void main(String[] args) {
        //创建集合
        HashSet<String> hashSet = new HashSet<>();
        //1. 添加元素
        hashSet.add("张学友");
        hashSet.add("郭富城");
        hashSet.add("刘德华");
        hashSet.add("黎明");
        System.out.println("元素个数:"+hashSet.size());
        System.out.println(hashSet);

        //2. 删除数据
//        hashSet.remove("黎明");
//        hashSet.clear();
//        System.out.println("删除之后"+hashSet.size());
//        System.out.println(hashSet);

        //3. 遍历
        //3.1 增强for
        System.out.println("--------增强for---------");
        for (String str : hashSet) {
            System.out.println(str);
        }
        //3.2 迭代器
        System.out.println("--------迭代器---------");
        Iterator<String> iterator = hashSet.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        //4. 判断
        System.out.println(hashSet.contains("刘德华"));
        System.out.println(hashSet.contains("刘亦菲"));
        System.out.println(hashSet.isEmpty());
    }
}

/**
 * HashSet集合的使用
 * 存储结构:哈希表(数组+链表(HDK1.7之前)+红黑树(JDK1.8之后))
 * 存储过程:
 * (1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空则执行第二步
 * (2)再执行equals方法,如果equals方法为true,则认为是重复的,否则,形成链表
 */
public class Set_HashSet02 {
    public static void main(String[] args) {
        //创建集合
        HashSet<Set_Person02> person = new HashSet<>();
        //1. 添加元素
        Set_Person02 p1 = new Set_Person02("刘德华",15);
        Set_Person02 p2 = new Set_Person02("郭富城",35);
        Set_Person02 p3 = new Set_Person02("梁朝伟",25);
        person.add(p1);
        person.add(p2);
        person.add(p3);
        //person.add(p3); 重复不能添加
        //person.add(new Set_Person02("郭富城",35)); new了一个对象,可以添加,但是名字和年龄一样
        //要想要相同的元素不能添加,那就要重写hashcode和equals方法
        person.add(new Set_Person02("郭富城",35));
        System.out.println("元素个数:"+person.size());
        System.out.println(person);

        //2. 删除元素
        //person.remove(p1);
//        person.remove(new Set_Person02("刘德华",15));
//        System.out.println("删除之后:"+person.size());
//        System.out.println(person);

        //3. 遍历
        //3.1 使用增强for
        System.out.println("-----------使用增强for-----------");
        for (Set_Person02 p : person) {
            System.out.println(p);
        }
        //3.2 使用迭代器
        System.out.println("-----------使用迭代器-----------");
        Iterator<Set_Person02> it = person.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        //4. 判断
        System.out.println(person.contains(p2));
        System.out.println(person.contains(new Set_Person02("梁朝伟",25)));
        System.out.println(person.isEmpty());
    }
}
//person类
public class Set_Person02 {
    private String name;
    private int age;

    public Set_Person02(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 "Set_Person02{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
//一键生成
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Set_Person02 person02 = (Set_Person02) o;
        return age == person02.age && Objects.equals(name, person02.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
//手动重写
//        @Override
//    public int hashCode() {
//        int n1 = this.name.hashCode();
//        int n2 = this.age;
//        return n1+n2;
//    }
//
//    @Override
//    public boolean equals(Object obj) {
//        if (this==obj) {
//            return true;
//        }
//        if (obj==null) {
//            return false;
//        }
//        if (obj instanceof Set_Person02) {
//            Set_Person02 person = (Set_Person02) obj;
//            if (this.name.equals(person.getName())&&this.age== person.getAge()) {
//                return true;
//            }
//        }
//        return false;
//    }
}

TreeSet

◆ TreeSet:

  1. 基于排序顺序实现元素不重复

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

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

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

/**
 * TreeSet的使用
 * 存储结构:红黑树
 */
public class Set_TreeSet01 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<String> treeSet = new TreeSet<>();
        //1. 添加元素
        treeSet.add("abc");
        treeSet.add("hello");
        treeSet.add("xyz");
        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
        System.out.println("----------增强for---------");
        for (String str : treeSet) {
            System.out.println(str);
        }
        //3.2 迭代器
        System.out.println("----------迭代器--------");
        Iterator<String> it = treeSet.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        //4. 判断
        System.out.println(treeSet.contains("hello"));
        System.out.println(treeSet.isEmpty());
    }
}

/**
 * TreeSet的使用
 * 存储结构:红黑树
 * 要求:元素必须要实现Comparable接口,compareTo()方法返回值为0,认为是重复元素
 */
public class Set_TreeSet02 {
    public static void main(String[] args) {
        //创建集合
        TreeSet<Set_Person02> person = new TreeSet<>();
        //1. 添加元素
        Set_Person02 p1 = new Set_Person02("xyz",15);
        Set_Person02 p2 = new Set_Person02("hello",35);
        Set_Person02 p3 = new Set_Person02("abc",25);
        Set_Person02 p4 = new Set_Person02("abc",15);
        person.add(p1);
        person.add(p2);
        person.add(p3);
        person.add(p4);
        System.out.println("元素个数:"+person.size());
        System.out.println(person);

        //2. 删除
        //person.remove(p1);
//        person.remove(new Set_Person02("abc",25));
//        System.out.println("删除之后:"+person.size());
//        System.out.println(person);

        //3. 遍历
        //3.1 使用增强for
        System.out.println("-------------使用增强for--------------");
        for (Set_Person02 s : person) {
            System.out.println(s);
        }
        //3.2 迭代器
        System.out.println("-------------使用迭代器--------------");
        Iterator<Set_Person02> iterator = person.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        //4. 判断
        System.out.println(person.contains(new Set_Person02("abc",25)));
        System.out.println(person.isEmpty());
    }
}

/**
 * TreeSet集合的使用
 * comparator(接口):实现定制比较(比较器)
 * Comparable(接口):可比较的
 */
public class Set_TreeSet03 {
    public static void main(String[] args) {
        //创建集合,并指定比较规则
        TreeSet<Set_Person02> person = new TreeSet<>(new Comparator<Set_Person02>() {
            @Override
            public int compare(Set_Person02 o1, Set_Person02 o2) {
                int n1 = o1.getAge()-o2.getAge();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1==0?n2:n1;
            }
        });

        Set_Person02 p1 = new Set_Person02("xyz",15);
        Set_Person02 p2 = new Set_Person02("hello",35);
        Set_Person02 p3 = new Set_Person02("abc",25);
        Set_Person02 p4 = new Set_Person02("khs",25);

        person.add(p1);
        person.add(p2);
        person.add(p3);
        person.add(p4);
        System.out.println(person);
    }
}

/**
 * 案例:
 * 要求:使用TreeSet集合实现字符串按照长度进行排序
 * hello world   zhangsan   huawei
 * Comparator接口实现定制比较规则
 */
public class Set_TreeSet04 {
    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("hello world");
        treeSet.add("zhangsan");
        treeSet.add("lisi");
        treeSet.add("huawei");
        treeSet.add("cat");
        treeSet.add("xian");

        System.out.println(treeSet.toString());

    }
}

Map集合

Map父接口

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

◆ 方法:

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

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

  3. Set<K> //返回所有key

  4. Collection<V> values() //返回包含所有值的Collection集合

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

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

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

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

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

Map实现类

HashMap

◆ HashMap:

  1. jdk1.2版本,线程不安全,运行效率快

  2. 允许用 null 作为 key 或是 value

◆ 存储结构:哈希表

◆ 重复依据:键的hashcode()方法和equals()方法

◆ 源码分析:

1 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16   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; //元素个数

◆ 源码分析总结:

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

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

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

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

  5. jdk1.8 以前,链表是头插入,jdk1.8 以后是尾插入

/**
 * HashMap集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 使用key的hashcode和equals作为重复的依据
 */
public class Map_HashMap {
    public static void main(String[] args) {
        //创建集合
        HashMap<Map_Student, String> students = new HashMap<>();
        //刚创建hsahmap之后没有添加元素 table=null size=0  目的:节省空间
        //1. 添加元素
        Map_Student student1 = new Map_Student("张三丰",25);
        Map_Student student2 = new Map_Student("令狐冲",22);
        Map_Student student3 = new Map_Student("任我行",31);
        students.put(student1, "武当");
        students.put(student2, "华山");
        students.put(student3, "魔教");
        //键不可重复,值可重复
        //想要以下的方式添加元素,添加不了,就需要重写hashcode和equals方法
        students.put(new Map_Student("任我行",31), "魔教");
        System.out.println("元素个数:"+students.size());
        System.out.println(students);

        //2. 删除元素
//        students.remove(student1);
//        System.out.println("删除之后:"+students.size());
//        System.out.println(students);

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

        //4. 判断
        System.out.println(students.containsKey(student1));
        System.out.println(students.containsKey(new Map_Student("令狐冲",22)));
        System.out.println(students.isEmpty());
        System.out.println(students.containsValue("魔教"));
    }
}
//学生类
public class Map_Student {
    private String name;
    private int stuNo;

    public Map_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 "Map_Student{" +
                "name='" + name + '\'' +
                ", stuNo=" + stuNo +
                '}';
    }

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

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

Hashtable

◆ Hashtable(开发上基本不用了):

  1. jdk1.0版本,线程安全,运行效率慢

  2. 不允许 null 作为 key 或是 value

Properties

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

TreeMap

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

/**
 * TreeMap的使用
 * 存储结构:红黑树
 */
public class Map_TreeMap {
    public static void main(String[] args) {
        //创建集合(如果不想实现Comparable接口,那就在创建集合的时候定制比较)
//        TreeMap<Map_Student, String> treeMap = new TreeMap<>(new Comparator<Map_Student>() {
//            @Override
//            public int compare(Map_Student o1, Map_Student o2) {
//                //这里写比较规则
//                return 0;
//            }
//        });
        TreeMap<Map_Student, String> treeMap = new TreeMap();
        //1. 添加元素,要求元素实现Comparable接口
        Map_Student s1 = new Map_Student("张三丰",25);
        Map_Student s2 = new Map_Student("令狐冲",22);
        Map_Student s3 = new Map_Student("任我行",31);
        treeMap.put(s1, "武当");
        treeMap.put(s2, "华山");
        treeMap.put(s3, "魔教");
        treeMap.put(new Map_Student("林平之",31), "峨眉");
        System.out.println("元素个数:"+treeMap.size());
        System.out.println(treeMap);

        //2. 删除
        //treeMap.remove(s1);
//        treeMap.remove(new Map_Student("令狐冲", 22));
//        System.out.println("删除之后:"+treeMap.size());
//        System.out.println(treeMap);

        //3. 遍历
        //3.1  keySet();
        System.out.println("----------keySet();------------");
        for (Map_Student s : treeMap.keySet()) {
            System.out.println(s+"------"+treeMap.get(s));
        }
        //3.2 entrySet();
        System.out.println("----------keySet();------------");
        for (Map.Entry<Map_Student, String> entry : treeMap.entrySet()) {
            System.out.println(entry.getKey()+"------"+entry.getValue());
        }

        //4. 判断
        System.out.println(treeMap.containsKey(s1));
        System.out.println(treeMap.containsKey(new Map_Student("令狐冲",22)));
    }
}

Colletions工具类

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

◆ 方法:

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

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

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

/**
 * Collection工具类的使用
 *
 */
public class Collections01 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(20);
        list.add(2);
        list.add(10);
        list.add(26);
        list.add(14);

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

        //二分查找 binarySearch
        int i = Collections.binarySearch(list, 10);
        System.out.println(i);

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

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

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

        //补充: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[] names = {"张三","李四","王五"};
        //通过这个方法转成的集合,是一个受限集合,不能添加和删除
        List<String> list3 = Arrays.asList(names);
        //list3.add("赵六");
        //list3.remove(1);
        System.out.println(list3);
        //把基本类型数组转成集合时,需要修改为包装类
        Integer[] nums = {100,200,300,150,500};
        List<Integer> list4 = Arrays.asList(nums);
        System.out.println(list4.toString());
    }
}

总结

◆ 集合的概念:

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

◆ LIst集合:

有序、有下标、元素可以重复。(ArrayList(存储结构:数组)、LinkedList(双向链表)、Vector(不常用))

◆ Set集合:

无序、无下标,元素不可重复。(HashSet(哈希表:数组+链表)、TreeSet(数组+链表+红黑树))

◆ Map集合:

存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap(哈希表)、HashTable(不常用)、TreeMap(红黑树))

◆ Collections:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值