《Java基础入门 极速版》

ch07 集合


图1 Java集合类是数据结构的实现

Java集合类是Java将一些基本的和使用频率极高的基础类进行封装和增强后再以一个类的形式提供。集合类是可以往里面保存多个对象的类,存放的是对象,不同的集合类有不同的功能和特点,适合不同的场合,用以解决一些实际问题。

【例题1】 集合

Java中的集合是一个名词,数据的一种容器,用于容纳数据。java.util.*

package cn.du.ch07;

public class Java01_Collection {
    public static void main(String[] args) {

        // TODO 集合
        // 生活中也有集合的概念。是一个动词

        // Java中的集合是一个名词,数据的一种容器,用于容纳数据
        // Java提供了完整的集合框架

        // TODO 问题:什么时候需要一个容纳数据的容器,也就是集合对象?
        //            Java集合框架中就包含了对不确定个数的数据处理的集合类
        // TODO 问题:如果只是为了容纳数据,可以是直接使用数组,为什么要学习集合?
        //           数组使用起来不方便。在数据个数不确定的场合,数组使用起来不是很方便

        // TODO 总结:对不确定的有关系的数据进行相同的逻辑处理的场合,使用集合是一个不错的选择

        // TODO 根据数据的不同,Java的集合分为2大体系:
        // 1. 单一数据体系 : Collection接口定义了相关的规则
        // 2. 成对出现的数据体系 : Map接口定义了相关的规则
        //    所谓的成对的数据,就是2个数据有关系,可以根据第一个数据关联到第二个数据
        //    也称之为键值对数据 ,(123123, zhangsan) => (key, value)
    }
}

【例题2】Collection接口(List,Set,Queue)和Map接口(HashMap, Hashtable)

Setpackage cn.du.ch07;

public class Java02_Collection {
    public static void main(String[] args) {

        // TODO 集合
        // 1. Collection接口
        //    常用的子接口
        //    List :按照插入顺序保存数据,数据可以重复的
        //         具体的实现类: ArrayList, LinkedList
        //    Set : 集,无序保存,数据不能重复
        //         具体的实现类 HashSet
        //    Queue : 队列
        //         具体的实现类:ArrayBlockingQueue
        // 2. Map接口
        //    具体的实现 : HashMap, Hashtable
    }
}
图2 Java集合类分类之1
图3 Java集合类分类之2

【例题3】 ArrayList基本操作

package cn.du.ch07;

import java.util.ArrayList;

public class Java03_Collection_List {
    public static void main(String[] args) {

        // TODO 集合 - Collection - List
        //            ArrayList : Array + List
        // TODO List : 列表,清单
        //      按照数据插入顺序进行存储
        // TODO Array : 数组,阵列

        // TODO 创建第一个集合对象:ArrayList
        ArrayList list = new ArrayList(3);
        // 1. 不需要传递构造参数,直接new就可以,底层数组为空数组
        // 2. 构造参数需要传递一个int类型的值,用于设定底层数组的长度
        // 3. 构造参数需要传递一个Collection集合类型的值,用于将其他集合中的数据放置在当前集合中

        // TODO 增加数据
        // add方法可以增加数据,只要将数据作为参数传递到add方法即可
        // 添加数据时,如果集合中没有任何的数据,那么底层会创建长度为10的数组
        list.add("杜老师");
        list.add("张三");
        list.add("张三");
        list.add("王五");
        list.add("赵六");
        // TODO 访问集合中的数据
        // 获取集合中数据的条数
        System.out.println("list.size() = "+list.size());
        // 获取指定位置的数据,可以采用索引的方式
        System.out.println("list.get(1) = " + list.get(1));
        System.out.println("list.get(2) = " + list.get(2));
        System.out.println();
        // 遍历集合中的数据
        System.out.println("集合中的数据:" );
        for ( int i = 0; i < list.size(); i++ ) {
            System.out.println("  索引i = " + i + " 数据:" + list.get(i));
        }

        // TODO 修改数据
        // 将指定位置的数据进行修改,set方法需要传递2个参数,第一个参数表示数据的位置,第二个参数修改的值。
        // 方法会返回结果,这个结果就是更新前的值
        System.out.println("\n修改前的值:" + list.get(2));
        Object oldVal = list.set(2, "李四");
        System.out.println("修改前的值:" + oldVal);
        System.out.println("修改后的值:" + list.get(2));
        System.out.println("修改后集合中的数据:");

        // TODO 如果循环遍历集合数据时,不关心数据的位置,那么可以采用特殊的for循环
        // for (循环对象:集合) {}
        for ( Object obj : list ) {
            System.out.print("  " + obj );
        }

        // TODO 删除数据
        // 将指定位置的数据进行删除,remove方法需要传递1个参数,参数表示数据的位置。
        // 方法会返回结果,这个结果就是删除的值
        Object removeVal = list.remove(2);
        System.out.println("\n\n删除的值:" + removeVal);

        // TODO 打印集合对象
        System.out.println("删除后 list = "+list);
        System.out.println("main方法执行完毕");
    }
}
图4 ArrayList基本操作
图5 ArrayList的自动扩容

【例题4】 ArrayList常用方法

package cn.du.ch07;

import java.util.ArrayList;

public class Java04_Collection_List_ArrayList {
    public static void main(String[] args) {

        // TODO 集合 - Collection - List
        // ArrayList的常用方法
        ArrayList list = new ArrayList();

        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("杜老师");
        list.add("杜老师");

        // add方法可以传递2个参数的,第一个参数表示数据增加的位置(索引),第二个参数表示数据
        list.add(1, "赵六");

        ArrayList otherList = new ArrayList();
        otherList.add("刘备");
        otherList.add("关羽");
        otherList.add("张飞");
        list.addAll( otherList );

        // size方法表示集合内部数据的数量
        System.out.println("list.size() = " + list.size());
        System.out.println("list = " + list);

        // 用于判断集合中是否存在某条数据,返回布尔类型的值
        System.out.println("list.contains(\"杜老师\") = " + list.contains("杜老师"));
        // 用于获取数据在索引中的第一个位置,如果数据不存在,那么返回-1
        System.out.println("list.indexOf(\"张山\") = " + list.indexOf("张山"));
        System.out.println("list.indexOf(\"张三\")" + list.indexOf("张三"));
        System.out.println("list.indexOf(\"杜老师\")" + list.indexOf("杜老师"));
        System.out.println("list.lastIndexOf(\"杜老师\")"+ list.lastIndexOf("杜老师"));

        Object[] objects = list.toArray();
        System.out.println("objects = "+objects);

        // 复制新集合
        Object clone = list.clone();
        ArrayList list1 = (ArrayList)clone;

        System.out.println("list = "+list);
        System.out.println("list1 = "+list1);

        // 删除指定集合中的数据
        list.removeAll(otherList);
        System.out.println("list.removeAll(otherList); otherList = " + otherList);
        System.out.println("                                list = " + list);
        // 判断集合中的数据是否为空
        System.out.println("list.isEmpty(): " + list.isEmpty());
        // 清空集合中的数据
        list.clear();
        System.out.println("list.clear(); list = "+list);
    }
}
图6 ArrayList常用方法

【例题5】LinkedList基本操作 链表

图7 LinkedList链表原理
package cn.du.ch07;

import java.util.LinkedList;

public class Java05_Collection_List_LinkedList {
    public static void main(String[] args) {

        // TODO 集合 - Collection - List
        // LinkedList : Linked(链接) + List
        // 构建集合对象
        LinkedList list = new LinkedList();

        // 增加第一个数据
        list.add("杜老师");
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.addFirst("李斯");
        list.add(1, "王武");

        // TODO 获取数据(遍历数据)
        System.out.print("遍历数据 list = ");
        for ( int i = 0; i < list.size(); i++ ) {
            System.out.print(list.get(i)+"    ");
        }

        // TODO 获取数据
        System.out.println("\nlist.getFirst() = "+list.getFirst());
        System.out.println("list.getLast()  = " + list.getLast());
        System.out.println("list.get(0)" + list.get(0));
        System.out.println("list.get(1)" + list.get(1));

        // 修改数据
        list.set(1, "赵六");
        // TODO 获取数据(遍历数据)
        System.out.print("\n遍历数据 list = ");
        for ( Object obj : list ) {
            System.out.print(obj+"    ");
        }

        // 删除数据
        list.remove("李斯");
        // TODO 打印集合数据
        System.out.println("\n删除数据后 list = "+list);

    }
}
图8 LinkedList之一 基本操作

【例题6】LinkedList常用方法

package cn.du.ch07;

import java.util.LinkedList;

public class Java05_Collection_List_LinkedList_1 {
    public static void main(String[] args) {

        // TODO 集合 - Collection - List
        // LinkedList : Linked(链接) + List
        // 构建集合对象
        LinkedList list = new LinkedList();

        // 追加数据
        list.add("杜老师");
        list.add("张三");
        list.add("李四");
        System.out.println("1.三次list.add('...') 之后。 list = "+list);

        // 想指定的位置增加数据
        list.add(1, "王五");
        list.addFirst("马云");
        list.addLast("孙山");
        System.out.println("2.list.addLast(\"孙山\"); 之后。 list = "+list);

        LinkedList list1 = new LinkedList();
        list1.add("刘备");
        list1.add("关羽");
        list1.add("张飞");
        list.addAll(list1);
        System.out.println("3.list.addAll(list1); 之后。 list = "+list);

        System.out.println("\n  list.remove(\"孙山\") = "+list.remove("孙山"));
        System.out.println("  list.remove() = "+list.remove()); // 删除第一个
        list.removeFirst();
        list.removeLast();
        list.remove(1);
        System.out.println("4.remove五次之后: ()|(1)(\"孙山\")|Last()|First() list = "+list);

        System.out.println("\n  list.size() = "+ list.size());
        System.out.println("  list.isEmpty() = "+list.isEmpty());
        System.out.println("  list.contains(\"关羽\") = "+list.contains("关羽"));
        System.out.println("  list.element() = "+list.element()); // 获取第一个数据
        System.out.println("  list.indexOf(\"刘备\") = "+list.indexOf("刘备"));
        System.out.println("  list.lastIndexOf(\"张飞\") = "+list.lastIndexOf("张飞"));
        System.out.println("5.list = "+list);

        list.push("aaa"); // 压入数据
        System.out.println("\n  "+list.pop()); // 弹出数据
        System.out.println("6.list = "+list);

        list.clear();
        System.out.println("\n7.list.clear(); 之后 list = "+list);
        System.out.println("  list.size() = "+ list.size());
        System.out.println("  list.isEmpty() = "+list.isEmpty());
     }
}
图9 LinkedList之二 常用方法
图10 Java集合API概览
图11 集合类常用操作方法

【例题7】泛型介绍

(1) 泛型

java泛型(generics)是JDK5中引入的一个新特性,泛型提供了编译时的类型安全检测机制, 该机制允许我们在编译时检测到非法的数据类型。

泛型的本质就是参数化类型,也就是所操作的数据类型被指定为一个参数。

泛型的好处:类型安全,消除了强制类型转换

泛型类注意事项:

(2) 泛型类

必须先声明,再使用。泛型的声明是通过 实现的,约定泛型可以使用单个大写字母来表示 如 T E K V 等等;泛型参数只能指定为引用类型,不能是基本数据类型;泛型类 如果在使用时不去指定具体的数据类型,则类型为Object。

package cn.du.ch07;

import java.util.ArrayList;

public class Java06_Collection {
    public static void main(String[] args) {

        // TODO 集合 - Collection
        // 泛型语法 Class ArrayList<E>
        System.out.println("ArrayList<E>【杜老师改编】");
        System.out.println("Person为User的父类:测试");
        User user = new User();
        user.testUser();

        Person person = new Person();
        person.testPerson();

        Person user1 = new User();
        //user1.testUser();  // 无法解析 'Person' 中的方法 'testUser'
        user1.testPerson();

        System.out.println("Person6、User6各组独立类:测试");
        // ArrayList<Person6> list = new ArrayList();
        ArrayList<Person6> list = new ArrayList<Person6>();

        User6 user6 = new User6();
        user6.testUser();

        Person6 person6 = new Person6();
        person6.testPerson();

        list.add(person6);
        //list.add(user6);  //ArrayList<Person6> list = new ArrayList(); 规定:需要的类型:Person6, 提供的类型: User6
        list.add(person6);
        list.remove(0);

        // 从集合中获取的对象类型为Object
        System.out.println("  从集合中获取的对象o,执行其o.testPerson()方法");
        Object o = list.get(0);
        // 如果想要执行对象的方法,那么需要进行强制类型转换
        if ( o instanceof  Person6 ) {
            Person6 p1 = (Person6)o;
            p1.testPerson();
        }
        Person6 p2 = list.get(0);
        p2.testPerson();
    }
}
class Person {
    public void testPerson() {
        System.out.println("  person...");
    }
}
class User extends Person {
    public void testUser() {
        System.out.println("  user...");
    }
}

class Person6 {
    public void testPerson() {
        System.out.println("  person6...");
    }
}
class User6 {
    public void testUser() {
        System.out.println("  user6...");
    }
}
图12 泛型介绍

【例题8】泛型基本使用

package cn.du.ch07;

public class Java07_Collection_Generic {
    public static void main(String[] args) {
        System.out.println("泛型和类型的区别【杜老师改编】");
        // TODO 集合 - Collection
        // 泛型语法
        // TODO 泛型和类型的区别
        // 有时,也把泛型称之为类型参数
        MyContainer<User7> myContainer = new MyContainer();
        //myContainer.data = new Object();
        myContainer.data = new User7();

        // 类型存在多态的使用方式,但是泛型没有多态的概念
        test(myContainer);
    }
    public static void test(MyContainer<User7> myContainer) {
        System.out.println(myContainer);
    }
}
// TODO 容器类
class MyContainer<C> {
    public C data;
}

class User7 {
}
图13 泛型和类型的区别
图14 泛型和类型的区别

【例题9】

package cn.du.ch07;

import java.util.ArrayList;
import java.util.Comparator;

public class Java08_Collection_Sort {
    public static void main(String[] args) {

        // TODO 集合 - Collection - List
        // Sort排序
        // 比较器: 实现了 Comparator<T> 的类
        System.out.println("比较器.排序【杜老师改编】");
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(4);
        list.add(2);
        list.add(3);
        list.add(8);
        list.add(7);
        System.out.println("排序前:"+list);

        // List对象进行排序,需要传递一个实现了比较器接口的对象
        list.sort(new NumberComparator());
        System.out.println("排序后:"+list);
    }
}
class NumberComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
//        if ( o1 < o2 ) {
//            return 1;     // if ( o1 < o2 ) return 1; 降序
//        } else if ( o1 == o2 ) {
//            return 0;
//        } else {
//            return -1;
//        }

        // T0DO 如果第一个数比第二个数要大,那么返回结果为正数,表示升序
        //return o1 - o2;
        // T0DO 如果第一个数比第二个数要小,那么返回结果为负数,表示降序
        // return o2 - o1;
        // T0DO 如果返回结果为0 不变顺序
        return 0;
    }
}
图15 比较器-升序
图16 比较器-降序
图17 比较器-不比较

【例题10】HashSet常用方法

package cn.du.ch07;

import java.util.ArrayList;
import java.util.HashSet;

public class Java09_Collection_Set_1 {
    public static void main(String[] args) {

        // TODO 集合 - Collection - Set
        // HashSet:  Hash + Set
        // Hash: 哈希算法,散列算法,
        // Set:集合

        HashSet set = new HashSet();
        // TODo 增加数据
        set.add("刘备");
        set.add("关羽");
        set.add("张飞");
        set.add("赵子龙");
        System.out.println("1.添加数据后 set = "+set);

        // TODo 修改数鹅:只能先删除、再添加
        // TODo 删除数据
        set.remove("赵子龙");
        // TODo 遍历数据
        System.out.print("2.删除数据后 set = ");
        for (Object o : set) {
            System.out.print("  "+o);
        }

        ArrayList list = new ArrayList();
        list.add("杜老师");
        list.add("张三");
        list.add("李四");
        list.add("王五");
        System.out.println("\n3.list = "+list);

        set.clear();
        set.addAll(list);
        System.out.println("4.清除数据又set.addall(list)  set = " + set);
        System.out.println("  set.isEmpty() = "+set.isEmpty());
        System.out.println("  set.contains(\"张三\") = "+ set.contains("张三"));
        System.out.println("  set.contains(\"张山\") = "+ set.contains("张山"));
        System.out.println("  set.size() = "+set.size());

        Object clone = set.clone();
        System.out.println("5.clone = "+clone);
        Object[] objects = set.toArray();
        System.out.println("6.objects = "+objects);
        set.clear();
        System.out.println("7.set.clear();后 set = " + set);
        System.out.println("  set.isEmpty() = "+set.isEmpty());
        System.out.println("  set.size() = "+set.size());
    }
}
图18 HashSet
图19 HashSet常用方法

【例题11】Set-HashSet数据重复

package cn.du.ch07;

import java.util.HashSet;

public class Java09_Collection_Set_2 {
    public static void main(String[] args) {

        // TODO 集合 - Collection - Set
        // HashSet 底层数据结构为 数组 + 链表
        System.out.println("HashSet数据重复【杜老师改编】");
        HashSet set = new HashSet();
        User9_ user1_ = new User9_();
        user1_.id = 1001;
        user1_.姓名 = "杜老师";
        System.out.println(user1_.hashCode());

        User9_ user2_ = new User9_();
        user2_.id = 1002;
        user2_.姓名 = "张三";
        System.out.println(user2_.hashCode());

        User9_ user3_ = new User9_();
        user3_.id = 1002;
        user3_.姓名 = "张三";
        System.out.println(user3_.hashCode());

        User9_ user4_ = new User9_();
        user4_.id = 1004;
        user4_.姓名 = "李四";
        System.out.println(user4_.hashCode());

        set.add(user1_);
        set.add(user2_);
        set.add(user3_);
        set.add(user4_);
        System.out.println("对象采用默认hashCode、equals算法的 set = "+set);

        set.clear();
        User9 user1 = new User9();
        user1.id = 1001;
        user1.姓名 = "杜老师";
        System.out.println(user1.hashCode());

        User9 user2 = new User9();
        user2.id = 1002;
        user2.姓名 = "张三";
        System.out.println(user2.hashCode());

        User9 user3 = new User9();
        user3.id = 1002;
        user3.姓名 = "张三";
        System.out.println(user3.hashCode());

        User9 user4 = new User9();
        user4.id = 1004;
        user4.姓名 = "李四";
        System.out.println(user4.hashCode());

        set.add(user1);
        set.add(user2);
        set.add(user3);
        set.add(user4);
        System.out.println("重写改写hashCode、equals算法的 set = "+set);

    }
}

class User9_ {
    public int id;
    public String 姓名;

    @Override
    public String toString() {
        return "User_["+id+", "+姓名+"]";
    }
}


class User9 {
    public int id;
    public String 姓名;

    @Override
    // 类似于内存地址
    public int hashCode() {
        return id;
    }

    @Override
    // 判断两个对象的属性是否完全相同
    public boolean equals(Object obj) {
        if ( obj instanceof User9 ) {
            User9 otherUser = (User9)obj;
            if ( otherUser.id == this.id ) {
                if ( otherUser.姓名.equals(this.姓名) ) {
                    return true;
                }
            }
            return false;
        } else {
            return false;
        }
    }

    @Override
    public String toString() {
        return "User["+id+", "+姓名+"]";
    }
}
图20 HashSet数据重复

【例题12】队列Queue

package cn.du.ch07;

import java.util.concurrent.ArrayBlockingQueue;

public class Java10_Collection_Queue {
    public static void main(String[] args) throws Exception  {

        // TODO 集合 - Collection - Queue  先进先出
        // ArrayBlockingQueue : Array + Blocking(阻塞,堵住) + Queue
        ArrayBlockingQueue queue1 = new ArrayBlockingQueue(5);  //ArrayBlockingQueue(4);
        // add方法如果增加数据增加不了,直接发生错误。
        queue1.add("杜老师");
        queue1.add("张三");
        queue1.add("李四");
        queue1.add("王五");
        queue1.add("赵六"); // 发生错误,Queue full
        System.out.println("queue.add(\"...\"); queue1 = "+queue1);
        queue1.poll();
        queue1.poll();
        queue1.poll();
        queue1.poll();
        System.out.println("4次 queue1.poll(); 之后 queue1 = "+queue1);

        ArrayBlockingQueue queue2 = new ArrayBlockingQueue(5);  //ArrayBlockingQueue(4);
        queue2.put("杜老师");
        queue2.put("张三");
        queue2.put("李四");
        System.out.print("\n第三个人排队:");
        System.out.println("queue2.put(\"李四\"); queue2 = "+queue2);
        queue2.put("王五");
        queue2.put("赵六");
        System.out.print("第五个人排队:");
        System.out.println("queue2.put(\"赵六\"); queue2 = "+queue2);

        System.out.print(queue2.take()+"  ");
        System.out.print(queue2.take()+"  ");
        System.out.print(queue2.take()+"  ");
        System.out.print(queue2.take()+"  ");
        System.out.println("4次 queue2.take() 之后; queue2 = "+queue2);

        ArrayBlockingQueue queue3 = new ArrayBlockingQueue(5);  //ArrayBlockingQueue(4);
        boolean b排队 = queue3.offer("杜老师");
        System.out.println("\nqueue3.offer(\"杜老师\") "+ b排队);
        queue3.offer("张三");
        queue3.offer("李四");
        queue3.offer("王五");
        queue3.offer("赵六");
        System.out.println("queue3.offer(\"赵六\") 之后 queue3 =  "+ queue3);

        System.out.println("queue3.size() = "+queue3.size());
        System.out.println("queue3.isEmpty() = "+queue3.isEmpty());
        System.out.println("queue3.contains(\"李四\") = "+queue3.contains("李四"));
        System.out.println(queue3);
        queue3.clear();
        System.out.println("queue3.clear();之后:queue3.isEmpty() = "+queue3.isEmpty());
        System.out.println("                    queue3.contains(\"李四\") = "+queue3.contains("李四"));
        System.out.println("queue3.clear();之后:queue3"+queue3);
    }
}
图21 队列

【例题13】HashMap

package cn.du.ch07;

import java.util.HashMap;
import java.util.concurrent.ArrayBlockingQueue;

public class Java11_Collection_Map {
    public static void main(String[] args) throws Exception  {

        // TODO 集合 - Map
        // HashMap : Hash + Map
        // 数据存储是无序
        HashMap map = new HashMap();
        System.out.println("HashMap基本操作【杜老师改编】");
        // 添加数据:put
        // 修改数据,put方法也可以修改数据,返回值就是被修改的值
        map.put("杜老师", "60岁");
        map.put("张三", "20岁");
        map.put("李四", "20岁");
        map.put("李四", "22岁");   // 键值 李四 重发覆盖
        map.put("王五", "31岁");
        System.out.println("map put数据后:"+map);

        System.out.println("\nmap.put(\"杜老师\", \"55\") = "+map.put("杜老师", "55"));
        System.out.println("map put数据后:"+map);

        // TODO 查询数据
        System.out.println("\nmap.get(\"李老师\")"+map.get("李老师"));
        System.out.println("map.get(\"杜老师\")"+map.get("杜老师"));

        // TODO 删除数据
        map.remove("李四");
        System.out.println("\nmap 删除数据后 "+map);
    }
}
图22 HashMap
图23 HashMap基本操作

【例题14】HashMap常用方法

package cn.du.ch07;

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

public class Java11_Collection_Map_1 {
    public static void main(String[] args) throws Exception  {

        // TODO 集合 - Map
        HashMap<String, String> map = new HashMap();
        System.out.println("HashMap常用方法【杜老师整理】");
        System.out.println("返回值是添加或修改前的数组:");
        // 添加数据
        System.out.println("  添加数据 map.put(\"a\", \"0\"); 返回值:"+map.put("a", "0"));
        System.out.println("  添加数据 map.put(\"c\", \"3\"); 返回值:"+map.put("c", "3"));
        // 修改数据
        Object oldVal = map.put("a", "1");
        System.out.println("  修改数据 map.put(\"a\", \"1\"); 返回值:"+ oldVal);
        // 添加数据,putIfAbsent如果不存在这个 key,则添加到 hashMap 中。反之不添加
        System.out.println("  添加数据 map.putIfAbsent(\"b\", \"2\"); 返回值:"+map.putIfAbsent("b", "2"));
        System.out.println("  添加数据 map.putIfAbsent(\"b\", \"3\"); 返回值:"+map.putIfAbsent("b", "3"));

        //  替换数据 replace 如果存在这个 key,则修改到 hashMap 中。反之不修改
        System.out.println("  替换数据 map.replace(\"c\", \"4\"); 返回值:"+map.replace("c", "4"));
        System.out.println("  替换数据 map.replace(\"d\", \"5\"); 返回值:"+map.replace("d", "5"));
        System.out.println("1.map = "+map);

        map.clear();
        map.put("杜老师", "76kg");
        map.put("张三", "50kg");
        map.put("李四", "60kg");
        map.put("王五", "63kg");
        System.out.println("2.map = "+map);

        // TODO 获取map集合中所有的key
        System.out.print("  获取map集合中所有的key: ");
        Set set = map.keySet();
        for (Object k : set) {
            System.out.print(k+"\t");
        }
        System.out.print("\n  获取map集合中所有的值:  ");
        for (Object k : set) {
            System.out.print(map.get(k)+"\t");
        }
        System.out.print("\n  获取map集合中所有的k-v对: ");
        for (Object k : set) {
            System.out.print(k+"="+map.get(k)+"; ");
        }

        System.out.println("\n  map.containsKey(\"张三\") = "+map.containsKey("张三"));
        System.out.println("  map.containsKey(\"张山\") = "+map.containsKey("张山"));
        System.out.println("  map.containsValue(\"60kg\") = "+map.containsValue("60kg"));
        System.out.println("  map.containsValue(\"65kg\") = "+map.containsValue("65kg"));
        Collection values = map.values();
        System.out.print("  获取map集合中所有的值:  ");
        for (Object v : values) {
            System.out.print(v+"\t");
        }

        // TODO 获取键值对对象
        System.out.print("\n  获取键值对对象:");
        Set<Map.Entry<String, String>> entries = map.entrySet();
        for (Map.Entry<String, String> entry : entries) {
            System.out.print(entry.getKey() + "=" + entry.getValue()+ "   ");
        }

        map.remove("张三");
        map.remove("李四", "60kg");
        map.remove("王五", "80kg");
        System.out.println("\nmap.remove 张三、李四、王五后:");
        System.out.println("  map.size() = "+ map.size());
        System.out.println("  map.isEmpty() = "+ map.isEmpty());
        System.out.println("3.map = "+map);

        Object clone = map.clone();
        System.out.println("4.clone = "+clone);
        map.clear();
        System.out.println("5.map.clear();后 map = "+map);
        System.out.println("  map.size() = "+ map.size());
        System.out.println("  map.isEmpty() = "+ map.isEmpty());

    }
}
图24 HashMap底层存储逻辑
图25 HashMap常用方法

【例题15】Hashtable介绍

package cn.du.ch08;
package cn.du.ch07;

import java.util.HashMap;
import java.util.Hashtable;

public class Java11_Collection_Map_2 {
    public static void main(String[] args) throws Exception  {

        // TODO 集合 - Map
        // Hashtable
        Hashtable table = new Hashtable();
        table.put(null, null);
        HashMap map = new HashMap();
        map.put(null, null);
//        table.put()
//                table.get()
//                        table.remove()
        // TODO 1. 实现方式不一样的 : 继承父类不一样
        // TODO 2. 底层结构的容量不同: HashMap(16), Hashtable(11)
        // TODO 3. HashMap的K,V都可以为null, Hashtable的K, V不能是null
        // TODO 4. HashMap的数据定位采用的是Hash算法,但是Hashtable采用的就是hashcode
        // TODO 5. HashMap的性能较高,但是Hashtable较低

    }
}

【例题16】HashMap 迭代器Iterator

package cn.du.ch07;

import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Set;

public class Java11_Collection_Map_3 {
    public static void main(String[] args) throws Exception  {

        // TODO 集合 - Map
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("a", 1);
        map.put("b", 2);
        map.put("c", 3);
        map.put("d", 4);
        System.out.println("1. map = "+map);

//        Set<String> keys = map.keySet();
//        for (String key : keys) {
//            if ( "b".equals(key) ) {
//                map.remove("b");
//            }
//            System.out.println(map.get(key));
//        }
//        ConcurrentModificationException 出错

        Set<String> keys = map.keySet();
        for (String key : keys) {
            if ( "d".equals(key) ) {
                map.remove("b");
            }
            System.out.println("  "+key + "= "+map.get(key));
        }
        System.out.println("2. map = "+map);

        // TODO 迭代器
        //Set<String> keys = map.keySet();
        Iterator<String> iterator = keys.iterator();
        // hasNext方法用于判断是否存在下一条数据
        while (iterator.hasNext()) {
            // 获取下一条数据
            String key = iterator.next();
            if("c".equals(key)) {
                // remove方法只能对当前数据删除
                iterator.remove();
            }
            System.out.println("  "+key+"="+map.get(key));
        }
        System.out.println("3. map = "+map);
    }
}
图26 迭代器Iterator

【例题17】Util

package cn.du.ch07;

import java.util.Arrays;
import java.util.List;

public class Java12_Collection_Util {
    public static void main(String[] args) throws Exception  {

        // TODO 集合 - Arrays
        System.out.println("Arrays的类方法util【杜老师改编】");
        int[] is = {30,50,20,10,40};
        int[] is1 = {10,20,30,40,50};
        int[] is2 = {10,20,30,40,50,6};
        System.out.println("is: "+is);
        System.out.println("Arrays.toString(is): "+Arrays.toString(is));

        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
        System.out.println("List<Integer> integers = "+integers);

        // 排序(默认为升序)
        Arrays.sort(is); // 1,2,3,4,5
        System.out.println("排序:"+Arrays.toString(is));

        // 二分查找法,排序后的数组
        System.out.println("二分查找30: "+Arrays.binarySearch(is, 30));
        System.out.println("二分查找15: "+Arrays.binarySearch(is, 15));

        // 数组的比较
        System.out.println("is: "+Arrays.toString(is));
        System.out.println("is1: "+Arrays.toString(is1));
        System.out.println("is2: "+Arrays.toString(is2));
        System.out.println("is,is1 数组全局的比较 "+Arrays.equals(is, is1));
        System.out.println("is1,is2 数组全局的比较 "+Arrays.equals(is2, is1));
        System.out.println("is1,is2 数组局部的比较 "+Arrays.equals(is2, 0, 5, is1, 0, 5));
    }
}
图27 Arrays的类方法

【例题18】集合 - 异常

package cn.du.ch07;

import java.util.*;

public class Java13_Collection_Exception {
    public static void main(String[] args) throws Exception  {

        // TODO 集合 - 异常问题
        // 1. java.lang.IllegalArgumentException
        //    设定集合容量时,如果参数为负数,就会发生错误
        // ArrayList list1 = new ArrayList(-1);

        // 2. java.util.NoSuchElementException
        //    从链表结构中获取数据,如果没有数据的场合,那么会发生异常
        //LinkedList list2 = new LinkedList();
        //System.out.println(list2.getFirst());

        // 3. java.lang.IndexOutOfBoundsException
        // 从集合中获取数据,索引不是按照底层的数据结构设定,而是按照数据的个数决定
        // 如果访问的集合是数组,那么索引范围就是0 到数组长度-1
        // 如果访问的集合是List,那么索引范围就是0 到数据长度-1
        ArrayList list3 = new ArrayList();
        list3.add("杜老师");
        //list3.get(3);

        // 4 java.util.ConcurrentModificationException
        HashMap map = new HashMap();
        map.put("a", "1");
        map.put("b", "2");
        map.put("c", "3");

        // HashMap一旦循环遍历时,那么如果修改数据,就会发生错误
        for (Object o : map.keySet()) {
            if ( "b".equals(o) ) {
                map.put("d", "4");
            }
            System.out.println(map.get(o));
        }

        // 对Map集合进行遍历操作过程中,对数据进行了修改,就会发生错误。
        Set set = map.keySet();
        for ( Object key : set ) {
            if ( "b".equals(key) ) {
                map.remove(key);
            }
            System.out.println(map.get(key));
        }
    }
}
图28 集合异常出错提示
图29 ch07 集合 源代码截图

java集合(超详细)

https://blog.csdn.net/zdl66/article/details/126251818


返回