第14章 集合——(4)Map

一、Map接口特点

Set接口和Map接口的联系与区别:

  1. Set底层存放的是:K-V,K:输入的要存放的对象,V:PRESENT常量
  2. Map存放的是:K-V,K和V:输入的要存放的对象

Map接口实现类的特点:(这里讲的是JDK8的Map接口特点)

  1. Map和Collection并列存在,用于保存具有映射关系的数据:Key-Value。
  2. Map中的Key和Value可以是任何引用数据类型的数据,会封装到HashMap$Node对象中。
  3. Map 中的 Key 不允许重复,可以为 null,但 key 为 null 只能有一个。
  4. Map 中的 Value 可以重复,可以为 null,value 为 null 可以有多个。
  5. 常用 String 类作为 Map 的 key。
  6. key 和 value 之间存在单向一对一关系,即通过指定的 key 总能找到对应的 value(get 方法)
import java.util.HashMap;
import java.util.Map;

@SuppressWarnings({"all"})
public class Map_ {
    public static void main(String[] args) {
        Map map = new HashMap();

        //(1)Map和Collection并列存在,用于保存具有映射关系的数据:Key-Value。
        //(2)Map中的Key和Value可以是任何引用数据类型的数据,会封装到HashMap$Node对象中。
        //(3)Map中的Key不允许重复,原因和HashSet一样
        //(4)Map中的Value可以重复
        //(5)Map的key和value都可以为null,但key为null只能有一个,value为null可以有多个
        //(6)常用String类作为Map的key
        //(7)key和value之间存在单向一对一关系,即通过指定的key总能找到对应的value(get方法)
        map.put("No1", "韩顺平");//Key:No1,Value:韩顺平
        map.put("No2", "张无忌");
        map.put("No2", "张三丰");//添加相同的key,就会替换原本的value
        map.put("No3", "韩顺平");
        map.put(null, null);
        map.put(null, "abc");//替换
        map.put("No4", null);
        map.put("No5", null);
        map.put(1, "赵敏");//1首先进行包装
        map.put(new Object(), "金毛狮王");

        System.out.println(map);
        //输出结果:{No2=张三丰, null=abc, No1=韩顺平, 1=赵敏, No4=null, No3=韩顺平, No5=null, java.lang.Object@1540e19d=金毛狮王}
        //通过get方法,传入key,会返回对应的value
        System.out.println(map.get("No2"));//张三丰
    }
}

        7.一对 k-v 放在一个 HashMap$Node 中。因为 Node 实现了 Entry 接口,所以有些书也说一对 k-v 就是一个 Entry。

//HashMap 的静态内部类 Node    
static class Node<K,V> implements Map.Entry<K,V> {
        //一对 k-v 放在一个 HashMap$Node 中
        //因为 Node 实现了 Entry 接口,所以有些书也说一对 k-v 就是一个 Entry
        final int hash;
        final K key;//键key
        V value;//值value
        Node<K,V> next;

        ...
     }

k-v 真正存放在 HashMap$Node 中,keySet 集合和 Values 集合只是指向了 HashMap$Node 中的 key 和 value 而已(引用)。为了方便遍历,keySet 集合中放置了所有 key 的引用,Values 集合中放置了所有 Value 的引用,一组 k-v 形成一个 Entry,所有 Entry 放置在 entrySet 集合中。

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

@SuppressWarnings({"all"})
public class MapSource_ {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("no1", "张无忌");//key:no1 value:张无忌
        map.put("no2", "韩顺平");//k-v
        map.put(new Car(), new Person());
        /*
        1.k-v 最终是 HashMap$Node node = newNode(hash, key, value, null)
            Node<K,V> newNode(int hash, K key, V value, Node<K,V> next) {
                return new Node<>(hash, key, value, next);
            }
            newNode 方法:返回一个 Node 对象
        2.为了方便遍历,创建了一个 entrySet 集合,该集合存放的元素类型是 Entry,一个 Entry 对象包含 k,v
          EntrySet<Entry<K,V>> : transient Set<Map.Entry<K,V>> entrySet;
          entrySet 集合中,定义的元素类型是 Map.Entry,但实际存放的是 HashMap$Node(HashMap$Node 实现了 Map.Entry)
        3.方便遍历:Map.Entry 提供了两个重要的方法-getKey()和getValue()方法
         */

        Set entrySet = map.entrySet();//entrySet集合:存放的元素类型是 Entry,Entry 中存放 k-v 的引用
        System.out.println(entrySet.getClass());//class java.util.HashMap$EntrySet
        for (Object obj: entrySet) {
            System.out.println(obj.getClass());//class java.util.HashMap$Node

            //为了从 HashMap$Node 中取出 k-v
            //1.先向下转型
            Map.Entry entry = (Map.Entry) obj;//向下转型,编译类型:Object -> Map.Entry
            //2.getKey():获取key值;getValue():获取key值
            System.out.println(entry.getKey() + "-" + entry.getValue());//no2-韩顺平,no1-张无忌

        }

        Set keySet = map.keySet();//keySet集合:存放key的引用
        System.out.println(keySet.getClass());//class java.util.HashMap$KeySet
        Collection values = map.values();//values集合:存放value的引用
        System.out.println(values.getClass());//class java.util.HashMap$Values

    }
}

class Car {}
class Person {}

二、Map接口方法

  • put:添加,当put的key值已存在,则替换。
  • remove:根据键删除映射关系。
  • get:根据键获取值。如果键存在,则返回对应的值;如果键不存在,则返回null。
  • size:获取元素个数。
  • isEmpty:判断个数是否为0。
  • clear:清除。
  • containsKey:查找键是否存在。
import java.util.HashMap;
import java.util.Map;

@SuppressWarnings({"all"})
public class MapMethod {
    public static void main(String[] args) {
        //put:添加,如果 put 的 key 已存在,则替换。
        Map map = new HashMap();
        map.put("邓超", new Book("", 100));
        map.put("邓超", "孙俪");//替换
        map.put("王宝强", "马蓉");
        map.put("宋喆", "马蓉");
        map.put("刘令博", null);
        map.put(null, "刘亦菲");
        map.put("鹿晗", "关晓彤");
        System.out.println(map);//{邓超=孙俪, 宋喆=马蓉, 刘令博=null, null=刘亦菲, 王宝强=马蓉, 鹿晗=关晓彤}

        //remove:根据键删除映射关系
        map.remove(null);
        System.out.println(map);//{邓超=孙俪, 宋喆=马蓉, 刘令博=null, 王宝强=马蓉, 鹿晗=关晓彤}

        //get:根据键获取值
        //     如果键存在,则返回对应的值
        //     如果键不存在,则返回null
        Object val = map.get("鹿晗");
        System.out.println("鹿晗对应的val = " + val);//关晓彤
        Object val1 = map.get("张三");
        System.out.println("张三对应的val1 = " + val1);//null

        //size:获取元素个数
        System.out.println("k-v的数量:" + map.size());//5

        //isEmpty:判断个数是否为0
        System.out.println(map.isEmpty());//false

        //clear:清除
        map.clear();
        System.out.println(map);//{}

        //containsKey:查找键是否存在
        System.out.println(map.containsKey("hsp"));//false

    }
}

class Book {
    private String name;
    private int num;

    public Book(String name, int num) {
        this.name = name;
        this.num = num;
    }
}

三、Map六大遍历方式

获取所有的 k-v:

  • keySet     (1)增强for循环 (2)迭代器
  • entrySet  (1)增强for循环 (2)迭代器

获取所有的 value:

  • values      (1)增强for循环 (2)迭代器
import java.util.*;

@SuppressWarnings({"all"})
public class MapFor {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("邓超", "孙俪");
        map.put("王宝强", "马蓉");
        map.put("宋喆", "马蓉");
        map.put("刘令博", null);
        map.put(null, "刘亦菲");
        map.put("鹿晗", "关晓彤");

        //第一组:通过 keySet 获取所有的 k-v
        //先取出所有的 key,再通过 key 取出对应的 value
        Set keySet = map.keySet();
        //(1)增强for循环——快捷键:iter
        System.out.println("======第1种方法======");
        for (Object key : keySet) {
            System.out.println(key + "-" + map.get(key));
        }
        //(2)迭代器
        System.out.println("======第2种方法======");
        Iterator iterator = keySet.iterator();
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key + "-" + map.get(key));
        }

        //第二组:通过 values 获取所有的 value
        Collection values = map.values();
        //(1)增强for循环
        System.out.println("======取出所有的value-增强for循环======");
        for (Object value : values) {
            System.out.println(value);
            /*包含2个“马蓉”。
                孙俪
                马蓉
                null
                刘亦菲
                马蓉
                关晓彤
             */
        }
        //(2)迭代器
        System.out.println("======取出所有的value-迭代器======");
        Iterator iterator1 = values.iterator();
        while (iterator1.hasNext()) {
            Object value =  iterator1.next();
            System.out.println(value);
        }

        //第三组:通过 entrySet 获取所有的 k-v
        Set entrySet = map.entrySet();//entrySet 集合中存放的元素编译类型是 Map.Entry,运行类型是 HashMap$Node
        //(1)增强for
        System.out.println("======第3种方法======");
        for (Object entry : entrySet) {
            Map.Entry m = (Map.Entry) entry;//向下转型
            System.out.println(m.getKey() + "-" + m.getValue());
        }
        //(2)迭代器
        System.out.println("======第4种方法======");
        Iterator iterator2 = entrySet.iterator();
        while (iterator2.hasNext()) {
            Object entry =  iterator2.next();
            Map.Entry m = (Map.Entry) entry;//向下转型
            System.out.println(m.getKey() + "-" + m.getValue());
        }
    }
}

四、Map课堂练习与小结

使用 HashMap 添加3个员工对象,要求:键:员工id,值:员工对象,并遍历显示工资>18000的员工(遍历方式最少2种)。员工类:姓名、工资、员工id。

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

@SuppressWarnings({"all"})
public class MapExercise {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("001", new Employee("赵", 19000, "001"));
        map.put("002", new Employee("钱", 10000, "002"));
        map.put("003", new Employee("孙", 20000, "003"));

        //第一种方法:entrySet + 增强for循环
        Set entrySet = map.entrySet();
        System.out.println("===entrySet + 增强for循环===");
        for (Object entry : entrySet) {
            Map.Entry m = (Map.Entry) entry;
            if (((Employee)m.getValue()).getSalary() > 18000) {
                System.out.println(m.getKey() + "-" + m.getValue());
            }
        }

        //第二种方法:keySet + 迭代器
        Set keySet = map.keySet();
        System.out.println("===keySet + 迭代器===");
        Iterator iterator = keySet.iterator();
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            if (((Employee)map.get(key)).getSalary() > 18000) {
                System.out.println(key + "-" + map.get(key));
            }
        }

    }
}

class Employee {
    private String name;
    private int salary;
    private String id;

    public Employee(String name, int salary, String id) {
        this.name = name;
        this.salary = salary;
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getSalary() {
        return salary;
    }

    public void setSalary(int salary) {
        this.salary = salary;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", salary=" + salary +
                ", id='" + id + '\'' +
                '}';
    }
}

四、HashMap

1.介绍

  • HashMap 是 Map 接口使用频率最高的实现类。
  • HashMap 是以 k-v 的方式来存储数据的,k-v 会封装到 HashMap$Node 对象中。
  • HashMap 中 key 不允许重复,可以为 null,但 key 为 null 只能有一个。
  • HashMap 中 value 允许重复,可以为 null,value 为 null 可以有多个。
  • 如果添加相同的 key,则会覆盖原来的 value,等同于修改。
  • 与 HashSet 一样,不保证映射的顺序,因为底层是以 hash 表的方式来存储的。
  • HashMap 没有实现同步,因此是线程不安全的。

2.底层机制

JDK7.0的 HashMap 底层实现“数组+链表”,JDK8.0的底层实现“数组+链表+红黑树”。

  • HashMap 底层维护了一个 table 数组,该数组存储了 HashMap$Node 类型的元素,默认为null。
  • 初始化加载因子 loadFactor = 0.75。
  • 第一次添加元素,数组table扩容至16,临界值threshold为16*0.75=12。(0.75为加载因子loadFactor)
  • 添加元素时,先得到 key 的哈希值,再转化为在 table 的索引。然后判断该索引处是否有元素:
    • 如果没有元素直接添加;
    • 如果有元素,判断该元素的 key 和准备添加的元素的 key 是否相等:
      • 如果相等,则替换 val;
      • 如果不相等,则判断该索引处是树结构还是链表结构,做出相应处理。
  • 如果添加时元素个数 > 临界值,则进行扩容。16(12)→32(24)→64(48)→...
  • 在Java8中,如果一条链表的元素个数 >= TREEIFY_THRESHOLD(默认是8),并且table的大小 >= MIN_TREEIFY_CAPACITY(默认是64),就会进行树化(红黑树)。
import java.util.HashMap;

@SuppressWarnings({"all"})
public class HashMapSource1 {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();
        hashMap.put("java", 10);
        hashMap.put("php", 20);
        hashMap.put("java", 20);//替换

        System.out.println(hashMap);//{java=20, php=20}

        /*源码:
          (1)HashMap 构造器:初始化加载因子 loadFactor = 0.75
            public HashMap() {
                this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
            }
            此时,HashMap$Node[] table = null

          (2)对基本数据类型进行自动装箱
            public static Integer valueOf(int i) {
                if (i >= IntegerCache.low && i <= IntegerCache.high)
                    return IntegerCache.cache[i + (-IntegerCache.low)];
                return new Integer(i);
            }

          (3)put方法:该方法会执行hash(key)得到key对应的hash值
            public V put(K key, V value) {
                return putVal(hash(key), key, value, false, true);
            }

          (4)hash方法
            涉及算法(h = key.hashCode()) ^ (h >>> 16) ^按位异或 >>>无符号右移16位
            为了让不同的key尽量得到不同的hash值
            static final int hash(Object key) {//key:"java"
                int h;
                return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
            }

          (5)putVal方法
            final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
               boolean evict) {
                //辅助变量
                Node<K,V>[] tab; Node<K,V> p; int n, i;

                //如果 table 数组为 null,或者长度为0,就将 table 数组扩容到16(第一次)
                if ((tab = table) == null || (n = tab.length) == 0)
                    n = (tab = resize()).length;

                //通过 hash 值得到元素在数组 table 中的索引位置i
                //1.如果该索引处没有元素,就创建一个 Node 对象,并将该Node添加到该索引位置
                if ((p = tab[i = (n - 1) & hash]) == null)//p指向索引位置i处的Node元素
                    tab[i] = newNode(hash, key, value, null);
                //2.如果该索引处有元素:
                else {
                    //辅助变量
                    Node<K,V> e; K k;

                    //第1种情况:如果该索引位置的元素和准备添加的元素的 key 的 hash 值相同
                    //         并且满足下面两个条件之一:
                    //        (1)该索引位置的元素的 key 和准备添加的元素的 key 是同一个对象
                    //        (2)准备添加的元素的 key 的equals()方法和该索引位置的元素的 key 比较后相同(非String类对象,equals的具体实现程序员自己决定)
                    //         就不能加入
                    if (p.hash == hash &&
                        ((k = p.key) == key || (key != null && key.equals(k))))
                        e = p;

                    //第2种情况:如果该索引处是一颗红黑树,就调用putTreeVal来进行添加
                    else if (p instanceof TreeNode)
                        e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);

                    //第3种情况:如果该索引位置处是一个链表,就使用for循环依次和该链表的每一个元素进行比较
                    //        (1)依次比较的过程中,如果有相同的情况,直接break
                    //        (2)依次比较后都不相同,则加入到该链表的最后
                    //         把元素添加到链表后,立即判断该链表是否已经达到8个结点
                    //         如果达到8个就调用treeifyBin()对当前这个链表进行树化(转成红黑树)
                    //         注意:在转成红黑树时,要进行判断,判断条件(table 为 null 或 table 数组的大小<MIN_TREEIFY_CAPACITY(64))
                    //         if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
                    //                 resize();
                    //         如果条件成立,先对table进行扩容
                    //         如果条件不成立,将table转成红黑树--->剪枝
                    else {
                        for (int binCount = 0; ; ++binCount) {//死循环
                            if ((e = p.next) == null) {
                                p.next = newNode(hash, key, value, null);
                                if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                                    treeifyBin(tab, hash);
                                break;//对应(2)
                            }
                            if (e.hash == hash &&
                                ((k = e.key) == key || (key != null && key.equals(k))))
                                break;//对应(1)
                            p = e;
                        }
                    }

                    if (e != null) { // existing mapping for key
                        V oldValue = e.value;
                        if (!onlyIfAbsent || oldValue == null)
                            e.value = value;//新 value 替换旧 value
                        afterNodeAccess(e);
                        return oldValue;
                    }
                }

                ++modCount;
                //每增加一个元素,就size++,如果 HashMap 中元素个数 > 临界值,就扩容
                if (++size > threshold)
                    resize();
                afterNodeInsertion(evict);
                return null;
            }

         */

    }
}

3.扩容机制

  • 第一次添加时,table数组扩容到16,临界值(threshold)是16*0.75=12(0.75是加载因子(loadFactor))。
  • 如果table数组使用到了临界值12,就会继续扩容到16*2=32,新的临界值是32*0.75=24。依次类推... 16(12)→32(24)→64(48)→128(96)...
  • 不管是在链表后缀接结点,还是在table新的索引位置上增加结点,都会增加table使用,size++。
  • 在Java8中,如果一条链表的元素个数 >= TREEIFY_THRESHOLD(默认是8),并且table的大小 >= MIN_TREEIFY_CAPACITY(默认是64),就会进行树化(红黑树),否则仍然采用数组扩容机制。
import java.util.HashMap;

@SuppressWarnings({"all"})
public class HashMapSource2 {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();
        for (int i = 1; i < 100; i++) {
            hashMap.put(i, "hello");
        }
        /*
        第 1 次添加元素,table 数组扩容到16,临界值为12
        table数组使用达到12,table数组再次扩容到32,临界值是24
        table数组使用达到24,table数组再次扩容到64,临界值是48
        table数组使用达到48,table数组再次扩容到128,临界值是96
        table数组使用达到96,table数组再次扩容到256,临界值是192
        ...
        注意:当向hashMap中增加一个Node,不管是添加到链表后,还是加在table的索引位置,都算是增加了一个table数组使用
         */

//        for (int i = 1; i <= 12; i++) {
//            hashMap.put(new AA(i), "hello");
//        }
        /*
        第 1 次添加元素,table 数组扩容到16,临界值为12,在索引为4的位置添加一个Node元素
        第 2-8 次添加元素,在 table 数组索引为 4 的位置的最后缀接一个结点,第 8 次添加后,table的索引为 4 的位置上:一个8结点的链表
        第 9 次添加元素,table 数组扩容到32,table 数组索引为 4 的位置上:一个9结点的链表
        第 10 次添加元素,table 数组扩容到64,table 数组索引为 36 的位置上:一个10结点的链表(位置由4变至36)
        第 11 次添加元素,树化,table 表容量不变,table 的索引为 36 的位置上:链表->红黑树
         */

        System.out.println(hashMap);
        /*
            {
            A{num=7}=hello,
            A{num=1}=hello,
            A{num=2}=hello,
            A{num=3}=hello,
            A{num=4}=hello,
            A{num=5}=hello,
            A{num=6}=hello,
            A{num=12}=hello,
            A{num=8}=hello,
            A{num=9}=hello,
            A{num=10}=hello,
            A{num=11}=hello}
         */


    }
}

class AA {
    private int num;

    public AA(int num) {
        this.num = num;
    }

    @Override
    public int hashCode() {
        return 100;
    }

    @Override
    public String toString() {
        return "\nA{" +
                "num=" + num +
                '}';
    }
}

五、Hashtable

1.介绍

  • Hashtable 存放的元素是键值对,即 K-V。
  • Hashtable 的键和值都不能为 null,否则会抛出 NullPointerException。
  • Hashtable 使用方法基本上和 HashMap 一样。
  • Hashtable 是线程安全的(synchronized),HashMap 是线程不安全的。

六、Properties

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
000000_【课程介绍 —— 写在前面的话】_Java学习概述笔记.pdf 010101_【第1JAVA概述及开发环境搭建】_JAVA发展概述笔记.pdf 010102_【第1JAVA概述及开发环境搭建】_Java开发环境搭建笔记.pdf 010201_【第2:简单Java程序】_简单Java程序笔记.pdf 010301_【第3Java基础程序设计】_Java数据类型笔记.pdf 010302_【第3Java基础程序设计】_运算符、表达式与语句笔记.pdf 010303_【第3Java基础程序设计】_判断与循环语句笔记.pdf 010401_【第4:数组与方法】_数组的定义及使用笔记.pdf 010402_【第4:数组与方法】_方法的声明及使用笔记.pdf 010403_【第4:数组与方法】_数组的引用传递笔记.pdf 010404_【第4:数组与方法】_Java新特性对数组的支持笔记.pdf 020501_【第5:面向对象基础】_面向对象、类与对象的定义笔记.pdf 020502_【第5:面向对象基础】_类与对象的进一步研究笔记.pdf 020503_【第5:面向对象基础】_封装性笔记.pdf 020504_【第5:面向对象基础】_构造方法与匿名对象笔记.pdf 020505_〖第5:面向对象基础〗_实例讲解—类设计分析(学生类)笔记.pdf 020506_【第5:面向对象基础】_String类笔记.pdf 020507_【第5:面向对象基础】_String类的常用方法.pdf 020508_【第5:面向对象基础】_引用传递及其应用笔记.pdf 020509_【第5:面向对象基础】_this关键字笔记.pdf 020510_【第5:面向对象基础】_static关键字笔记.pdf 020511_【第5:面向对象基础】_理解main方法笔记.pdf 020512_【第5:面向对象基础】_代码块笔记.pdf 020513_【第5:面向对象基础】_构造方法私有化笔记.pdf 020514_【第5:面向对象基础】_对象数组笔记.pdf 020515_【第5:面向对象基础】_内部类笔记.pdf 020516_〖第5:面向对象基础〗_实例讲解—系统登陆笔记.pdf 020517_〖第5:面向对象基础〗_实例讲解—单向链表(1)笔记.pdf 020518_〖第5:面向对象基础〗_实例讲解—单向链表(2)笔记.pdf 020601_【第6:面向对象(高级)】_继承的基本实现笔记.pdf 020602_【第6:面向对象(高级)】_继承的进一步研究笔记.pdf 020603_〖第6:面向对象(高级)〗_范例:继承的应用笔记.pdf 020604_【第6:面向对象(高级)】_final关键字笔记.pdf 020605_【第6:面向对象(高级)】_抽象类的基本概念笔记.pdf 020606_【第6:面向对象(高级)】_接口的基本概念笔记.pdf 020607_【第6:面向对象(高级)】_对象的多态性笔记.pdf 020608_【第6:面向对象(高级)】_instanceof关键字笔记.pdf 020609_【第6:面向对象(高级)】_抽象类与接口的应用笔记.pdf 020610_〖第6:面向对象(高级)〗_实例分析:宠物商店笔记.pdf 020611_【第6:面向对象(高级)】_Object类笔记.pdf 020612_【第6:面向对象(高级)】_包装类笔记.pdf 020613_【第6:面向对象(高级)】_匿名内部类笔记.pdf 020701_【第7:异常的基本概念】_异常的基本概念笔记.pdf 020702_【第7:异常的基本概念】_异常的其他概念笔记.pdf 020801_【第8:包及访问控制权限】_包的定义及导入笔记.pdf 020802_【第8:包及访问控制权限】_访问控制权限及命名规范笔记.pdf 030901_【第9:多线程】_认识多线程笔记.pdf 030902_【第9:多线程】_线程常用操作方法笔记.pdf 030903_〖第9:多线程〗_线程操作范例笔记.pdf 030904_【第9:多线程】_同步与死锁笔记.pdf 030905_【第9:多线程】_线程操作案例——生产者和消费者笔记.pdf 030906_【第9:多线程】_线程生命周期笔记.pdf 031001_【第10:泛型】_泛型入门笔记.pdf 031002_【第10:泛型】_通配符笔记.pdf 031003_【第10:泛型】_泛型的其他应用笔记.pdf 031004_〖第10:泛型〗_实例讲解—泛型操作范例笔记.pdf 031101_【第11Java常用类库】_StringBuffer笔记.pdf 031102_【第11Java常用类库】_Runtime类笔记.pdf 031103_【第11Java常用类库】_国际化程序笔记.pdf 031104_【第11Java常用类库】_System类笔记.pdf 031105_【第11Java常用类库】_日期操作类(Date、Calendar)笔记.pdf 031106_【第11Java常用类库】_日期操作类(DateFormat、SimpleDateFormat)笔记.pdf 031107_〖第11Java常用类库〗_实例操作:取得当前日期笔记.pdf 031108_【第11Java常用类库】_Math与Random类笔记.pdf 031109_【第11Java常用类库】_NumberFormat笔记.pdf 031110_【第11Java常用类库】_大数操作(BigIntger、BigDecimal)笔记.pdf 031111_【第11Java常用类库】_对象克隆技术笔记.pdf 031112_【第11Java常用类库】_Arrays笔记.pdf 031113_【第11Java常用类库】_比较器(Comparable、Comparator)笔记.pdf 031114_【第11Java常用类库】_观察者设计模式笔记.pdf 031115_【第11Java常用类库】_正则表达式笔记.pdf 031116_【第11Java常用类库】_定时调度笔记.pdf 031201_【第12JAVA IO】_File类笔记.pdf 031202_【第12JAVA IO】_RandomAccessFile笔记.pdf 031203_【第12JAVA IO】_字节流与字符流笔记.pdf 031204_【第12JAVA IO】_字节-字符转换流笔记.pdf 031205_【第12JAVA IO】_内存操作流笔记.pdf 031206_【第12JAVA IO】_管道流笔记.pdf 031207_【第12JAVA IO】_打印流笔记.pdf 031208_【第12JAVA IO】_System类对IO的支持笔记.pdf 031209_【第12JAVA IO】_BufferedReader笔记.pdf 031210_〖第12JAVA IO〗_IO操作实例笔记.pdf 031211_【第12JAVA IO】_Scanner笔记.pdf 031212_【第12JAVA IO】_数据操作流笔记.pdf 031213_【第12JAVA IO】_合并流笔记.pdf 031214_【第12JAVA IO】_压缩流笔记.pdf 031215_【第12JAVA IO】_回退流笔记.pdf 031216_【第12JAVA IO】_字符编码笔记.pdf 031217_【第12JAVA IO】_对象序列化笔记.pdf 031218_〖第12JAVA IO〗_实例操作—单人信息管理程序笔记.pdf 031219_〖第12JAVA IO〗_实例操作:投票程序笔记.pdf 031301_【第13Java类集】_认识类集、Collection接口笔记.pdf 031302_【第13Java类集】_List接口笔记.pdf 031303_【第13Java类集】_LinkedList类笔记.pdf 031304_【第13Java类集】_Set接口笔记.pdf 031305_【第13Java类集】_排序及重复元素说明笔记.pdf 031306_【第13Java类集】_SortedSet接口笔记.pdf 031307_【第13Java类集】_Iterator接口笔记.pdf 031308_【第13Java类集】_ListIterator接口笔记.pdf 031309_【第13Java类集】_foreach及Enumeration接口笔记.pdf 031310_【第13Java类集】_Map接口笔记.pdf 031311_【第13Java类集】_Map接口使用的注意事项笔记.pdf 031312_【第13Java类集】_IdentityHashMap类笔记.pdf 031313_【第13Java类集】_SortedMap类笔记.pdf 031314_【第13Java类集】_集合工具类:Collections笔记.pdf 031315_【第13Java类集】_Stack类笔记.pdf 031316_【第13Java类集】_属性类:Properties笔记.pdf 031317_〖第13Java类集〗_范例讲解:一对多关系笔记.pdf 031318_〖第13Java类集〗_范例讲解:多对多关系笔记.pdf 031401_【第14:枚举】_枚举的作用笔记.pdf 031402_【第14:枚举】_Enum笔记.pdf 031403_【第14:枚举】_类集对Enum的支持笔记.pdf 031404_【第14:枚举】_枚举的其他应用笔记.pdf 031501_【第15Java反射机制】_认识Class类笔记.pdf 031502_【第15Java反射机制】_Class类的使用笔记.pdf 031503_【第15Java反射机制】_反射应用——取得类的结构笔记.pdf 031504_【第15Java反射机制】_Java反射机制的深入研究笔记.pdf 031505_【第15Java反射机制】_动态代理笔记.pdf 031506_【第15Java反射机制】_工厂设计模式笔记.pdf 031601_【第16:Annotation】_系统内建Annotation笔记.pdf 031602_【第16:Annotation】_自定义Annotation笔记.pdf 031603_【第16:Annotation】_反射与Annotation笔记.pdf 031604_【第16:Annotation】_深入Annotation笔记.pdf 031701_【第17Java数据库编程】_JDBC概述笔记.pdf 031702_【第17Java数据库编程】_MySQL数据库笔记.pdf 031703_【第17Java数据库编程】_SQL语法基础笔记.pdf 031704_【第17Java数据库编程】_JDBC操作步骤及数据库连接操作笔记.pdf 031705_【第17Java数据库编程】_执行数据库更新操作笔记.pdf 031706_【第17Java数据库编程】_ResultSet接口笔记.pdf 031707_【第17Java数据库编程】_PreparedStatement接口笔记.pdf 031708_【第17Java数据库编程】_处理大数据对象(1)—处理CLOB数据笔记.pdf 031709_【第17Java数据库编程】_处理大数据对象(2)—处理BLOB数据笔记.pdf 031710_【第17Java数据库编程】_CallableStatement接口笔记.pdf 031711_【第17Java数据库编程】_JDBC 2.0操作笔记.pdf 031712_【第17Java数据库编程】_事务处理笔记.pdf 031713_【第17Java数据库编程】_使用元数据分析数据库笔记.pdf 031714_【第17Java数据库编程】_使用JDBC连接Oracle笔记.pdf 031801_【第18:图形界面】_AWT、Swing简介笔记.pdf 031802_【第18:图形界面】_基本容器:JFrame笔记.pdf 031803_【第18:图形界面】_标签组件:JLabel笔记.pdf 031804_【第18:图形界面】_按钮组件:JButton笔记.pdf 031805_【第18:图形界面】_布局管理器笔记.pdf 031806_【第18:图形界面】_其他容器笔记.pdf 031807_【第18:图形界面】_不弹起的按钮组件:JToggleButton笔记.pdf 031808_【第18:图形界面】_文本组件:JTextComponent笔记.pdf 031809_【第18:图形界面】_事件处理笔记.pdf 031810_【第18:图形界面】_单选钮:JRadioButton笔记.pdf 031811_【第18:图形界面】_复选框:JCheckBox笔记.pdf 031812_【第18:图形界面】_列表框:JList笔记.pdf 031812_【第18:图形界面】_下拉列表框:JComboBox笔记.pdf 031813_【第18:图形界面】_菜单组件笔记.pdf 031814_【第18:图形界面】_文件选择框笔记.pdf 031815_【第18:图形界面】_表格笔记.pdf 031901_【第19Java网络编程】_IP(Internet Protocol)与InetAddress笔记.pdf 031902_【第19Java网络编程】_URL与URLConnection笔记.pdf 031903_【第19Java网络编程】_URLEncoder与URLDecoder笔记.pdf 031904_【第19Java网络编程】_TCP程序设计笔记.pdf 031905_【第19Java网络编程】_UDP程序设计笔记.pdf 032001_【第20Java新IO】_缓冲区与Buffer笔记.pdf 032002_【第20Java新IO】_通道(Channel)笔记.pdf 032003_【第20Java新IO】_文件锁笔记.pdf 032004_【第20Java新IO】_字符集笔记.pdf 032005_【第20Java新IO】_Selector笔记.pdf 042101_【课程讲解】_附录:Eclipse开发工具笔记.pdf 050101_〖开发实例〗_Java开发实例讲解(人员管理)笔记.pdf

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值