Java 集合框架

早在 Java 2 中之前,Java 就提供了特设类。比如:Dictionary, Vector, Stack, 和 Properties 这些类用来存储和操作对象组。

Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。

List 接口

List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。
List 接口存储一组不唯一,有序(插入顺序)的对象。

Java 集合框架


package com.hspedu.collection_;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author 山河与you皆无恙
 */

public class Collection_ {
    @SuppressWarnings("all")
    public static void main(String[] args) {
        //1.集合主要是两组(单列集合,双列集合)
        //2.Collection 接口有两个重要的子接口 List Set,他们的实现子类都是单列集合
        //3.Map 接口的实现子类是 双列集合,存放的 K-V
        //4.两张图很重要,需要记住
        //Collection
        //Map
        ArrayList arrayList = new ArrayList();
        arrayList.add("jack");
        arrayList.add("tom");
        HashMap hashMap = new HashMap();
        hashMap.put("NO1","北京");
        hashMap.put("NO2","上海");

    }
}

List 方法使用

package com.hspedu.collection_;

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

/**
 * @author 山河与you皆无恙
 */

public class CollectionMethod {
    @SuppressWarnings("all")
    public static void main(String[] args) {
        List list = new ArrayList();
//      add:添加某个元素
        list.add("jack");
        list.add(10);//list.add(new Integer(10))
        list.add(true);
        System.out.println("List"+list);
//      remove:删除指定元素
//      list.remove(0);//删除第一个元素
        list.remove(true);
//      cotains:查找元素是否存在
        System.out.println(list.contains("jack"));
//      size:获取元素个数
        System.out.println(list.size());
//      isEmpty:判断元素是否为空
        System.out.println(list.isEmpty());
//      clear:清空
        list.clear();
        System.out.println("List"+list);
//      addall:
        ArrayList list2 = new ArrayList();
        list2.add("红楼梦");
        list2.add("三国演义");
        list.addAll(list2);
        System.out.println("List"+list);
//      containsall:查找多个元素是否存在
        System.out.println(list.containsAll(list2));//true
        list.add("聊斋");
//      removeall:删除多个元素
        list.removeAll(list2);
        System.out.println("List"+list);
//      说明:以ArrayList实现来演示
    }

}

增强for和迭代器遍历

package com.hspedu.collection_;

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

/**
 * @author 山河与you皆无恙
 */

public class CollectionFor {
    @SuppressWarnings("all")
    public static void main(String[] args) {
        Collection col = new ArrayList();
        col.add(new Book("三国演义","罗贯中",10.1));
        col.add(new Book("小李飞刀","古龙",10.1));
        col.add(new Book("红楼梦","曹雪芹",34.6));
        //1.使用增强for,在Collection集合
        //2.增强for,底层仍然是迭代器
        //3.增强for可以理解为简化版的迭代器遍历
        //4.快捷键 I
//        for (Object book:col) {
//            System.out.println("Book"+book);
//        }
        for (Object o :col) {
            System.out.println("Book"+o);
        }

    }
}


package com.hspedu.collection_;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/**
 * @author 山河与you皆无恙
 */

public class CollectionIterator {
    @SuppressWarnings("all")
    public static void main(String[] args) {
        Collection col = new ArrayList();
        col.add(new Book("三国演义","罗贯中",10.1));
        col.add(new Book("小李飞刀","古龙",10.1));
        col.add(new Book("红楼梦","曹雪芹",34.6));
        //1.遍历集合
        System.out.println("col="+col);
        //先得到 Iterator的迭代器
        Iterator iterator = col.iterator();
        //2.使用while循环遍历
//        while (iterator.hasNext()) {//判断是否还有数据
//            //返回下一个元素,类型是 Object
//            Object obj  =  iterator.next();
//            System.out.println("obj"+obj);
//
//        }
        //快捷键生成 while循环遍历=》itit+enter(即回车)
        //显示所有快捷键的快捷键 ctrl+j
        while (iterator.hasNext()) {
            Object obj =  iterator.next();
            System.out.println("obj"+obj);
        }
        //当退出while以后,这时iterator迭代器指向最后的元素
        //iterator.next();//NoSuchElmentException
        //如果需要再次遍历,需要重置我们的迭代器
        iterator = col.iterator();
        System.out.println("=======第二次遍历=======");
        while (iterator.hasNext()) {
            Object obj =  iterator.next();
            System.out.println("obj"+obj);

        }
    }


}
class  Book{
    private String name;
    private String author;
    private double price;

    public Book(String name, String author, double price) {
        this.name = name;
        this.author = author;
        this.price = price;
    }

    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + ''' +
                ", author='" + author + ''' +
                ", price=" + price +
                '}';
    }
}

collections

java.util.Collections 是一个包装类。它包含有各种有关集合操作的 静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

package com.hspedu.collections_;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * @author 山河与you皆无恙
 */

@SuppressWarnings({"all"})
public class Collections_ {
    //创建 ArrayList 集合 用于测试
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("tom");
        list.add("smith");
        list.add("king");
        list.add("milan");
        System.out.println("list= "+list);

        //reverse(list):反转list中的元素的是顺序
        Collections.reverse(list);
        //shuffle(list):对list中的元素进行随机排序
        System.out.println("list= "+list);
//        for (int i = 0; i <5 ; i++) {
//            Collections.shuffle(list);
//            System.out.println("list= "+list);
//        }
        //sort(list):对集合list中的元素自然排序
        Collections.sort(list);
        System.out.println("list= "+list);
        //按照字符串长度比较
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length()-((String)o2).length();
            }
        });
        System.out.println("字符串长度大小= "+list);
        //将指定 list 集合中的i 处元素和j处元素进行交换
        //wap(list,1,2)
        Collections.swap(list,1,2);
        System.out.println("交换后= "+list);

        //Object max(Collectionn):根据元素自然排序,返回给定集合中的最大元素
        System.out.println("自然排序最大元素="+Collections.max(list));
        //比如返回最大的元素
        //根据Comparator指定的顺序,返回给定集合中的最大元素
        Object maxObject = Collections.max(list, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length()-((String)o2).length();
            }
        });
        System.out.println("长度最大的元素="+maxObject);
        //int frequency(Collection,Object)) 返回指定集合中指定元素的出现次数
        System.out.println("tom出现的次数="+Collections.frequency(list,"tom"));
        //void copy(List dest,List src) 将src中的内容复制到dest中
        ArrayList dest = new ArrayList();
        //为了完成完整拷贝,先给 dest 赋值,大小和 list,size()大小一样
        for (int i = 0; i <list.size() ; i++) {
            dest.add("");
        }
        //拷贝
        Collections.copy(dest,list);
        System.out.println("dest="+dest);
        //boolearn replaceAll(List list,Object oldVal,Object newVal):使用新值替换 List 对象的所有旧值
        boolean b = Collections.replaceAll(list, "tom""汤姆");
        System.out.println("list替换后= "+list);
    }

}

ArrayList

该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。

ArrayList执行过程

Java 集合框架

Java 集合框架


package com.hspedu.list_;

import java.util.ArrayList;

/**
 * @author 山河与you皆无恙
 */

@SuppressWarnings({"all"})
public class ArrayListSource {
    public static void main(String[] args) {
        //注意,注意,注意,idea 默认情况下, Debug 显示的数据是简化后的,如果希望看到完整的数据需要做设置
        //使用无参构造器创建 ArrayList 对象
        //ArrayList list = new ArrayList();
        ArrayList list = new ArrayList(8);
        //使用for给list集合添加1—10数据
        for (int i = 0; i <=10 ; i++) {
            list.add(i);

        }
        //用for给list集合添加11-15
        // 数据
        for (int i = 11; i <15 ; i++) {
            list.add(i);
        }
        list.add(100);
        list.add(200);
        list.add(null);
    }
}


LinkedList

该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:

List list=Collections.synchronizedList(newLinkedList(…));
LinkedList 查找效率低。

package com.hspedu.list_;

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

/**
 * @author 山河与you皆无恙
 */

@SuppressWarnings({"all"})
public class LinkedListCRUD {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.add(1);
        linkedList.add(2);
        linkedList.add(3);
        System.out.println("linkedList"+linkedList);
        //演示一个删除结点的
        linkedList.remove();//这里默认删除的是第一个结点
        System.out.println("linkedList"+linkedList);
        //修改某个结点对象
        linkedList.set(1,999);
        System.out.println("linkedList"+linkedList);
        //得到某个结点的对象
        //get(1)是得到双向链表的第二个对象
        Object o = linkedList.get(1);
        System.out.println(0);
        //因为linkedList是实现了list接口方式,遍历方式
        System.out.println("=============linedList遍历迭代器============");
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println(next);
        }
        System.out.println("=============linedList遍历增强for============");
        for (Object o1 :linkedList) {
            System.out.println("o1=0"+o1);
        }
        System.out.println("=============linedList遍历普通for============");
        for (int i = 0; i <linkedList.size() ; i++) {
            System.out.println(linkedList.get(i));
        }



        /*//1.LinkedList linkedList = new LinkedList();
            public LinkedList {}

            2.这时LinkedList的属性 first =null last =null
            3. 执行、添加
                public boolean add(E e) {
                    linkLast(e);
                    return true;
                }
            4.
                    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++;
            }
        */

           /* linkedList.remove();//这里默认删除的是第一个结点
            1.执行
                   public E remove() {
                      return removeFirst();
                    }
            2.执行
            public E removeFirst() {
                final Node<E> f = first;
                if (f == null)
                    throw new NoSuchElementException();
                return unlinkFirst(f);
            }

            3.执行 unlinkFirst 将f指向的第一个结点拿掉
                   private E unlinkFirst(Node<E> f) {
                // assert f == first && f != null;
                final E element = f.item;
                final Node<E> next = f.next;
                f.item = null;
                f.next = null; // help GC
                first = next;
                if (next == null)
                    last = null;
                else
                    next.prev = null;
                size--;
                modCount++;
                return element;
            }
          */

    }
}

Set

Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。
Set 接口存储一组唯一,无序的对象。

HashSet

该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。

package com.hspedu.set_;

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

/**
 * @author 山河与you皆无恙
 */

@SuppressWarnings({"all"})
public class HashSet_ {
    public static void main(String[] args) {
       /* 1.构造器走的源码
          2.HashSet 可以存放null 但是只能有一个null,即元素不能重复
       */

        Set hashSet = new HashSet();
        hashSet.add(null);
        hashSet.add(null);
        System.out.println("hashSet= "+hashSet);
    }
}


package com.hspedu.set_;

import java.util.HashSet;

/**
 * @author 山河与you皆无恙
 */

@SuppressWarnings({"all"})
public class HashSetSource {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        hashSet.add("java");
        hashSet.add("php");
        hashSet.add("java");
        System.out.println("set="+hashSet);


       /*
           1.执行HashSet()
           public HashSet() {
                map = new HashMap<>();
            }
           2.执行add()
            public boolean add(E e) {//e="java"
                return map.put(e, PRESENT)==null;//(static)  PRESENT = new Object();
            }
           3.执行put(),该方法会执行 hash(key)得到 key 对应的 hash 值 算法(h = key.hashCode()) ^ (h >>> 16)
            public V put(K key, V value) {//key="java" value = PRESENT 共享
                return putVal(hash(key), key, value, false, true);
            }
           4.执行
                 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 就是 HashMap 的一个数组,类型是 Node[]
            //if语句表示如果当前 table 是null,或者大小=0
            //就是第一次扩容到16个空间
            if ((tab = table) == null || (n = tab.length) == 0)
                n = (tab = resize()).length;
            //(1)根据key 得到hash 去计算该key应该存放到索引表的哪个索引位置
            //并把这个位置的对象赋给p
            //(2)判断 p 是否为null
            //(2.1)如果 p 为null,表示还没有存放元素,就创建一个 Node(Key = "java",value = PRESENT)
            //(2.2)就放在该位置tab[i] = newNode(hash, key, value, null)
            if ((p = tab[i = (n - 1) & hash]) == null)
                tab[i] = newNode(hash, key, value, null);
            else {
            //一个开发技巧提示,:在创建局部变量(辅助变量)的时候,在创建
                Node<K,V> e; K k;
                if (p.hash == hash &&
                    ((k = p.key) == key || (key != null && key.equals(k))))
                    e = p;
                else if (p instanceof TreeNode)
                    e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
                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;
                        }
                        if (e.hash == hash &&
                            ((k = e.key) == key || (key != null && key.equals(k))))
                            break;
                        p = e;
                    }
                }
                if (e != null) { // existing mapping for key
                    V oldValue = e.value;
                    if (!onlyIfAbsent || oldValue == null)
                        e.value = value;
                    afterNodeAccess(e);
                    return oldValue;
                }
            }
            ++modCount;
            if (++size > threshold)
                resize();
            afterNodeInsertion(evict);
            return null;
        }
        */

    }
}

Vector

该类和ArrayList非常相似,但是该类是同步的,可以用在多线程的情况,该类允许设置默认的增长长度,默认扩容方式为原来的2倍。

package com.hspedu.list_;

import java.util.Vector;

/**
 * @author 山河与you皆无恙
 */


@SuppressWarnings({"all"})
public class Vector_ {
    public static void main(String[] args) {
//        Vector vector = new Vector();
        Vector vector = new Vector(8);
        for (int i = 0; i <=10; i++) {
            vector.add(i);
        }

        /*
        //1.Vector底层
         public Vector() {
        this(10);
         }
        //2.Vector.add()
        //2.1添加数据到Vector集合
        public synchronized boolean add(E e) {
            modCount++;
            ensureCapacityHelper(elementCount + 1);
            elementData[elementCount++] = e;
            return true;
        }
        补充:如果是Vector vector = new Vector(8)
        走的方法
        public Vector(int initialCapacity) {
        this(initialCapacity, 0);
    }
        //确定是否需要扩容 条件:minCapacity - elementData.length > 0
        private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
     }
        //如果需要的数组大小不够用,就扩容,扩容的算法,就是扩容2倍
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
        }
        */


    }
}


Map

Map 接口存储一组键值对象,提供key(键)到value(值)的映射。

Java 集合框架


package com.hspedu.map_;

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

/**
 * @author 山河与you皆无恙
 */

@SuppressWarnings({"all"})
public class Map_ {
    public static void main(String[] args) {
        //Map实现类的特点,使用实现类HashMap
        //1.Map与Collection并列存在,用于保存具有映射关系的数据:key-value(双列元素)
        //2.Map 中的 key 和 value 可以是任何类型的数据,会封装到 HashMap$Node 对象中
        //3.Map 中的 key 不允许重复,原因和 HashSet 一样,前面源码已经分析
        //4.Map 中的 value 可以重复
        //5.注意:Map 中的 key 可以为null,value也可以为null, Map 中的key为null只能有一个,value为null可以多个
        //6.常用String类作为Map的key
        Map map = new HashMap();
        map.put("no1","韩顺平");//k-v
        map.put("no2","张无忌");//k-v
        map.put("no1","张三丰");//k-v 当有相同的 k,就等价于替换。
        map.put("no3","张三丰");//k-v
        map.put(null,null);//k-v
        map.put(null,"abc");//k-v 等价替换
        map.put("no4",null);//k-v
        map.put("no5",null);//k-v
        System.out.println("map="+map);
        //通过get方法 传入 key,会返回对应的 value
        System.out.println(map.get("no2"));
    }
}

HashMap

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。

package com.hspedu.map_;

import java.util.HashMap;

/**
 * @author 山河与you皆无恙
 */

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


      /*
         1.执行构造器 new HashMap
           初始化加载因子 loadFactor
           HashMap$Node[] table = null
          public HashMap() {
            this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted
        }
        2.执行put 调用Hash方法,计算 key的hash值 (h = key.hashCode()) ^ (h >>> 16)
          public V put(K key, V value) {//key="java" value =10
            return putVal(hash(key), key, value, false, true);
        }
        3.执行 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,或者 length = 0就扩容到16
            if ((tab = table) == null || (n = tab.length) == 0)
                n = (tab = resize()).length;
            //取出hash值对应的table索引位置的Node,如果为null,就直接把加入的k-v
            //,创建成一个Node,加入该位置即可
            if ((p = tab[i = (n - 1) & hash]) == null)
                tab[i] = newNode(hash, key, value, null);
            else {
                Node<K,V> e; K k;//辅助变量
                //如果 table 的索引位置的key的hash值和新的key的hash值相同
                //并满足(table 现有结点的key和准备添加的key是同一个对象 || equals 返回真)
                //就认为不能加入行的key
                if (p.hash == hash &&
                    ((k = p.key) == key || (key != null && key.equals(k))))
                    e = p;
                else if (p instanceof TreeNode)//如果当前的table的已有的 Node 是红黑树,就按照红黑树的方式处理
                    e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
                else {//如果找到的结点,后面是链表,就循环比较
                    for (int binCount = 0; ; ++binCount) {//死循环
                        if ((e = p.next) == null) {//如果整个链表没有和它相同,就加到链表的最后,
                            p.next = newNode(hash, key, value, null);
                            //加入后 就判断当前链表的个数,是否已经到8个,后
                            //就调用 treeifyBin 方法进行红黑树转换
                            if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                                treeifyBin(tab, hash);
                            break;
                        }
                        if (e.hash == hash &&//如果在循环比较过程中,发现有相同,就 break,就只是替换 value
                            ((k = e.key) == key || (key != null && key.equals(k))))
                            break;
                        p = e;
                    }
                }
                if (e != null) { // existing mapping for key
                    V oldValue = e.value;
                    if (!onlyIfAbsent || oldValue == null)
                        e.value = value;//替换 key 对应的值
                    afterNodeAccess(e);
                    return oldValue;
                }
            }
            ++modCount;//没增加一个 Node,就size++
            if (++size > threshold)//如size>临界值(12-24-48----),就扩容
                resize();
            afterNodeInsertion(evict);
            return null;
        }

       5.关于树化(转成红黑树)
       //如果 table 为 null 或者大小还没有到 64 暂时不树化,而是进行扩容
       //否则才会真正的树化->剪枝
           final void treeifyBin(Node<K,V>[] tab, int hash) {
                int n, index; Node<K,V> e;
                if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
                    resize();

           */

    }
}

遍历方式

package com.hspedu.map_;

import java.util.*;

/**
 * @author 山河与you皆无恙
 */

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

        //1.第一组:先取出所有的key,通过key取出对应的value
        //(1)增强for
        System.out.println("================第一种方式================");
        Set keySet = map.keySet();
        for (Object key : keySet) {
            System.out.println(key+"-"+map.get(key));
        }
        System.out.println("================第二种方式================");
        Iterator iterator = keySet.iterator();
        while (iterator.hasNext()) {
            Object key =  iterator.next();
            System.out.println(key+"-"+map.get(key));
        }
        //第二组:把所有的Values取出
        Collection values = map.values();
        //这里可以使用所有 Collection 的方法
        //(1)增强for
        System.out.println("=============取出所有的value 增强for(第1种)==============");
        for (Object value :values) {
            System.out.println(value);

        }
        //(2)迭代器
        System.out.println("=============取出所有的value 迭代器(第2种)==============");
        Iterator iterator2 = values.iterator();
        while (iterator2.hasNext()) {
            Object value =  iterator2.next();
            System.out.println(value);
        }
        //第三组:通过EntreySet 来获取k—v
        System.out.println("=============使用EntrySet的for增强(第3种)==============");
        Set entrySet = map.entrySet();
        for (Object entry :entrySet) {
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey()+"-"+m.getValue());
        }
        //第四组:通过EntrySet的 迭代器来获取k—v
        System.out.println("=============使用EntrySet的 迭代器(第4种)==============");
        Iterator iterator3 = entrySet.iterator();
        while (iterator3.hasNext()) {
            Object entry =  iterator3.next();
            System.out.println(entry );//HashMap$Node->实现 Map.Entry(getKey,getValue)
            Map.Entry m = (Map.Entry) entry;
            System.out.println(m.getKey()+"-"+m.getValue());
        }
    }
}

TreeMap

继承了AbstractMap,并且使用一颗树。

package com.hspedu.map_;

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

/**
 * @author 山河与you皆无恙
 */

@SuppressWarnings({"all"})
public class TreeMap_ {
    public static void main(String[] args) {
        //使用默认的构造器创建TreeMap 是无序
        //按照传入的 k(String)的大小进行排序
        //TreeMap treeMap = new TreeMap();
        TreeMap treeMap = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //按照传入的 k(String)的大小进行排序
               // return ((String) o1).compareTo((String) o2);
                //按照字符串长度进行比较
                return ((String) o1).length()-((String) o2).length();
            }
        });
        treeMap.put("jack","杰克");
        treeMap.put("tom","汤姆");
        treeMap.put("kristina","克瑞斯提诺");
        treeMap.put("smith","斯密斯");
        System.out.println("treeMap="+treeMap);


        /*
        1.构造器把传入的比较器对象,赋给了 TreeSet 的底层的 TreeMap 的属性this.comparator
            public TreeMap(Comparator<? super K> comparator) {
                this.comparator = comparator;
            }
        2.调用put方法
          2.1 第一次添加 把 K V封装到 Entry 对象,放入 root
            Entry<K,V> t = root;
            if (t == null) {
                compare(key, key); // type (and possibly null) check
                root = new Entry<>(key, value, null);
                size = 1;
                modCount++;
                return null;
            }
          2.2 以后添加
          Comparator<? super K> cpr = comparator;
          if (cpr != null) {
            do {//遍历所有的key 给当前的key 找到适当的位置
                parent = t;
                cmp = cpr.compare(key, t.key);//动态绑定到我们的匿名内部类的compare
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else//如果遍历过程中,发现准备添加key 和当前已有的 Key 相等,就不添加
                    return t.setValue(value);
            } while (t != null);
        }
        */

    }
}

TreeSet

该类实现了Set接口,可以实现排序等功能。

package com.hspedu.map_;

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

/**
 * @author 山河与you皆无恙
 */

@SuppressWarnings({"all"})
public class TreeSet_ {
    public static void main(String[] args) {
        TreeSet treeSet = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //return ((String)o2).compareTo((String)o1);
                //按照长度大小比较
                return ((String)o1).length()-((String)o2).length();
            }
        });
        //添加数据
        treeSet.add("jack");
        treeSet.add("tom");
        treeSet.add("sp");
        treeSet.add("a");
        treeSet.add("abc");//加入不了
        System.out.println("treeSet="+treeSet);
        /*
        1.构造器把传入的比较器对象,赋给了 TreeSet 的底层的 TreeMap 的属性this.comparator
            public TreeMap(Comparator<? super K> comparator) {
                this.comparator = comparator;
            }
        2.在调用 treeSet.add("tom"),会执行到
            if (cpr != null) {//cpr就是我们的匿名内部类(对象)
            do {
                parent = t;
                //动态绑定到我们的匿名内部类对象compare
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else//如果相等,即返回0,这个key就没有加入
                    return t.setValue(value);
            } while (t != null);
        }
        */

    }
}

纸上得来终觉浅,绝知此事要躬行!

Java 集合框架


原文始发于微信公众号(itmkyuan):Java 集合框架

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/39471.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!