·Java集合类能够用于存储数量差异的多少个指标,那么些法子再次回到的结果也是依照目标的地点转换而来的

宣示:那篇博文纯属是近年来看源码时闲着没事瞎折腾(好奇心驱动),对实际的应用程序编码作者觉得说不定没有那么大的佑助,各位亲就当是代码写累了放松放松心境,视为偏门小传说看一看就足以了,别深究。

Java集合概述

3.3 集合

  • 单向,
    面向对象语言对事物的呈现都以以指标的花样,为了有利于对多少个指标的操作,就要对目的举办仓库储存。另一方面,使用Array存储对象方面具备局地弊端,而Java
    集合就像是一种容器,能够动态地把多少个目的的引用放入容器中。
  • Java
    集合类能够用于存款和储蓄数量分裂的多少个指标,还可用于保存具有映射关系的关周到组。

Java 集合可分为 Collection 和 Map 二种种类

  • Collection接口:
  • Set:成分无序、不可重复的成团 —类似高级中学的“集合”
  • List:元素有序,可另行的聚合 —”动态”数组
  • Map接口:具有映射关系“key-value对”的汇集 —类似于高级中学的“函数” y =
    f(x) (x1,y1) (x2,y2)

一、从Object和System谈起

·一方面,面向对象语言对事物的反映都以以目的的款型,为了便于对八个指标的操作,就要对指标开始展览仓库储存。另一方面,使用Array存款和储蓄对象方面抱有局地害处,而Java集合就像是一种容器,能够动态地吧三个对象的引用放入容器中。

3.3.1 Collection接口

  • Collection 接口是 List、Set 和 Queue
    接口的父接口,该接口里定义的方法既可用来操作 Set 集合,也可用以操作
    List 和 Queue 集合。
  • JDK不提供此接口的别样直接促成,而是提供更有血有肉的子接口(如:Set和List)达成。
  • 在 Java5 从前,Java
    集合会丢失容器中装有指标的数据类型,把具备目的都真是 Object
    类型处理;从 Java5 扩大了泛型未来,Java
    集合能够记住容器中目的的数据类型

Collection接口继承树

图片 1

会晤中数组间转换操作:

方法类型 方法
Object[] toArray() 返回包含此collection中所有元素的数组
<T> T[] toArray(T[] a) 返回包含此 collection中所有元素的数组;返回数组的运行时类型与指定数组的运行时类型相同

首先是Object类中的hashCode()方法:

·Java集合类能够用来存款和储蓄数量不一样的五个对象,还可用来保存具有映射关系的关联数组。

3.3.1.1 Iterator接口

  • Iterator对象称为迭代器(设计格局的一种),重要用来遍历 Collection
    集合中的成分。
  • 不无达成了Collection接口的集合类都有一个iterator()方法,用以重临二个兑现了Iterator接口的对象。
  • Iterator 仅用于遍历集合,Iterator
    本人并不提供承装对象的能力。假设要求创建 Iterator
    对象,则必须有2个被迭代的相会。

Iterator接口措施:

图片 2

在调用iterator.next()方法在此之前必须求调用iterator.hasNext()进行检查和测试。
若不调用,且下一条记下无效,直接调用iterator.next()会抛出NoSuchElementException非凡。

//List的知识将在下面讲到。这里先做演示
List l=new ArrayList();
//因为Collection framework只能存储对象所以new封装类
l.add(new Integer(1));
l.add(new Integer(2));
l.add(new Integer(3));
l.add(new Integer(4));
Iterator x = l.iterator();

while(x.hasNext()){
   Object o = x.next();
   System.out.println(o);
}

输出结果:

1
2
3
4

java5中提供了foreach循环迭代做客Collection

代码示例

class Persons{
    public String name ;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    Persons(){
    }
    Persons(String name){
        this.name = name;
    }
    public static void main(String[] args) {
        List<Persons> persons  = new ArrayList<Persons>();
        persons.add(new Persons("张三"));
        persons.add(new Persons("李四"));
        persons.add(new Persons("王五"));
        persons.add(new Persons("赵六"));

        for(Persons person: persons){
            System.out.println(person.getName());
        }
        //其中:  
        //Persons 代表要遍历的元素类型
        //person 代表遍历后元素名称
        //persons 代表要遍历的元素名称
    }
}

出口结果:

张三
李四
王五
赵六
public native int hashCode();

·Java集合可分为Collection和Map两种种类

3.3.1.2 List接口

  • Java中数组用来存款和储蓄数据的局限性
  • List集合类中成分有序、且可重复,集合中的各类元素都有其对应的顺序索引。
  • List容器中的成分都对应3个平头型的序号记载其在容器中的地方,能够依照序号存取容器中的成分。
  • JDK API中List接口的落实类常用的有:ArrayList、LinkedList和Vector。
  • List 集合里添加了一些遵照索引来操作集合成分的法门

  • void add(int index, Object ele)
  • boolean addAll(int index, Collection eles)
  • Object get(int index)
  • int indexOf(Object obj)
  • int lastIndexOf(Object obj)
  • Object remove(int index)
  • Object set(int index, Object ele)
  • List subList(int fromIndex, int toIndex)

ArrayList

  • ArrayList 是 List 接口的卓著达成类
  • 实为上,ArrayList是目的引用的3个变长数组
  • ArrayList 是线程不安全的,而 Vector 是线程安全的,尽管为保险 List
    集合线程安全,也不推荐使用Vector
  • Arrays.asList(…) 方法重回的 List 集合既不是 ArrayList 实例,也不是
    Vector 实例。Arrays.asList(…) 再次来到值是叁个一定长度的 List 集合

LinkedList

  • 对此频仍的插入或删除成分的操作,建议采纳LinkedList类,功用较高

  • 新增方法:

           void addFirst(Object obj)
           void addLast(Object obj)   
           Object getFirst()
           Object getLast()
           Object removeFirst()
           Object removeLast()
    

代码示例

        // List 接口的链接列表实现
        LinkedList<String> list = new LinkedList<String>();

        list.push("one");
        list.push("two");
        list.push("three");
        list.push("four");

        Iterator<String> lit = list.iterator();
        while (lit.hasNext()) {
            System.out.println(list.pop());
        }

        System.out.println(list.size() + "---------");

出口结果:

four
three
two
one
0---------

Vector

  • Vector
    是二个古老的集合,JDK1.0就有了。超越1/2操作与ArrayList相同,区别之处在于Vector是线程安全的。

  • 在各类list中,最好把ArrayList作为缺省选取。当插入、删除频仍时,使用LinkedList;Vector总是比ArrayList慢,所以尽量防止使用。

  • 增加产量方法:

  • void addElement(Object obj)

  • void insertElementAt(Object obj,int index)

  • void setElementAt(Object obj,int index)

  • void removeElement(Object obj)

  • void removeAllElements()

代码示例

Vector<String> v = new Vector<String>();// 10

// 同步
v.add("one");
v.add("two");
v.add("three");
v.add("one");
v.add("two");
v.add("three");

for (int i = 0; i < v.size(); i++) {
    System.out.print(v.get(i)+" ");
}
System.out.println("v.size() = "+v.size());

System.out.println("使用insertElementAt方法");
v.insertElementAt("啊哈", 0);
for (int i = 0; i < v.size(); i++) {
    System.out.print(v.get(i)+" ");
}
System.out.println("v.size() = "+v.size());

System.out.println("使用remove方法");
v.remove(0);
for (int i = 0; i < v.size(); i++) {
    System.out.print(v.get(i)+" ");
}
System.out.println("v.size() = "+v.size());

System.out.println("使用removeAllElements方法");
v.removeAllElements();
for (int i = 0; i < v.size(); i++) {
    System.out.print(v.get(i)+" ");
}
System.out.println("v.size() = "+v.size());

出口结果:

one two three one two three v.size() = 6
使用insertElementAt方法
啊哈 one two three one two three v.size() = 7
使用remove方法
one two three one two three v.size() = 6
使用removeAllElements方法
v.size() = 0

LinkedList、ArrayList和Vector区别

1.ArrayList是最常用的List达成类,内部是透过数组达成的,它同意对成分实行快捷随机走访。数组的缺点是种种成分之间不能够有距离,当数组大小不满意时索要追加存款和储蓄能力,就要讲曾经有数组的数额复制到新的仓库储存空间中。当从ArrayList的中档地方插入恐怕去除成分时,须要对数组实行复制、移动、代价比较高。因而,它符合自由查找和遍历,不合乎插入和删除。

2.Vector与ArrayList一样,也是经过数组完结的,区其余是它协助线程的一道,即某一天天只有八个线程能够写Vector,幸免多线程同时写而引起的分裂性,但落实共同供给很高的消费,因而,访问它比访问ArrayList慢。

3.LinkedList是用链表结构存款和储蓄数据的,很合乎数据的动态插入和删除,随机访问和遍历速度比较慢。此外,他还提供了List接口中绝非定义的点子,专门用于操作表头和表尾成分,能够看成储藏室、队列和双向队列使用。

ArrayList和Vector的区别。

一.同步性:Vector是线程安全的,也正是说是共同的,而ArrayList是线程序不安全的,不是一道的
二.数据增加:当须要增强时,Vector暗中认可增加为本来一培,而ArrayList却是原来的六分之三

ArrayList 默认量:0 -10  增量 原来一半   
Vector  默认量: 10 增量 原来的一倍。

举行精晓:ListIterator接口

  • List 额外提供了二个 listIterator() 方法,该措施再次回到三个 ListIterator
    对象, ListIterator 接口继承了 Iterator 接口,提供了特别操作 List
    的点子:
  • void add()
  • boolean hasPrevious()
  • Object previous()
  • Boolean hasNext()
  • Object next()

Iterator和ListIterator首要分歧
一 、ListIterator和Iterator都有hasNext()和next()方法,能够实现顺序向后遍历。但是ListIterator有hasPrevious()和previous()方法,能够达成逆向(顺序向前)遍历。Iterator就不得以。
二 、ListIterator能够一定当前的目录地方,nextIndex()和previousIndex()能够达成。Iterator
没有此成效。
③ 、ListIterator有add()方法,可以向List中插入对象,而Iterator无法。
④ 、都可完成删除对象,然而ListIterator能够兑现指标的改动,set()方法能够完成。Iterator仅能遍历,无法修改。因为ListIterator的这个成效,能够兑现对LinkedList等List数据结构的操作。

native修饰的法子。可是依照文书档案的叙述,我们精通这几个int类型的hashCode是根据目的的地址转换而来的。

  Collection接口:

3.3.1.3 Set接口

  • Set接口是Collection的子接口,set接口没有提供额外的措施
  • Set 集合分裂意包括相同的成分,若是试把多个相同的因素参预同3个 Set
    集合中,则增长操作战败。
  • Set 判断七个指标是不是同样不是运用 == 运算符,而是依照 equals 方法

引文:

    Set:成分无序、不可重复的聚众 —类似于高级中学的聚众

Set完毕类之一 HashSet

  • HashSet 是 Set 接口的高人一头达成,半数以上时候利用 Set
    集合时都接纳这么些达成类。
  • HashSet 按 Hash
    算法来存款和储蓄集合中的成分,因而有着很好的存取和寻找质量。
  • HashSet 具有以下特征:
  • 无法担保成分的排列顺序
  • HashSet 不是线程安全的
  • 集合成分能够是 null
  • 当向 HashSet 集合中存入1个因素时,HashSet 会调用该对象的 hashCode()
    方法来赢得该指标的 hashCode 值,然后根据 hashCode 值决定该对象在
    HashSet 中的存款和储蓄地方。
  • HashSet 集合判断五个成分相等的标准:多个目的通过 hashCode()
    方法比较相等,并且多少个指标的 equals() 方法重临值也就是。

代码示例

Set<String> set = new HashSet<String>();// ctrl+shift+O
set.add("one");
set.add("one");
set.add("two");
set.add("three");
set.add("four");
/*
 * for(int i=0;i<set.size();i++){ set. }
 */
System.out.println("长度:" + set.size());

Iterator<String> it = set.iterator();

while (it.hasNext()) {
    System.out.println(it.next());
}

出口结果:

长度:4
four
one
two
three

As much as is reasonably
practical, the hashCode method defined by class Object does return
distinct integers for distinct objects. (This is typically implemented
by converting the internal address of the object into an integer, but
this implementation technique is not required by the Java™ programming
language.)。

    List:成分有序、可另行的集聚    —动态数组

HashCode()

  • 设若八个成分的 equals() 方法重回 true,但它们的 hashCode()
    重临值不等于,hashSet
    将会把它们存储在差异的岗位,但还是可以添加成功。
  • 对此存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object
    obj)方法,以达成目标相等规则。
  • 重写 hashCode() 方法的为主尺度:
  • 在程序运营时,同多个对象往往调用 hashCode() 方法应该回到相同的值
  • 当四个对象的 equals() 方法相比较再次来到 true 时,那四个目的的 hashCode()
    方法的重临值也应格外
  • 对象中用作 equals() 方法比较的 Field,都应该用来总计 hashCode 值

然后是System类的静态方法:identityHashCode(Object x)

  Map接口:具有映射关系“key-value对”的汇聚 —类似于高级中学的“函数”

Set实现类之二 LinkedHashSet

  • LinkedHashSet 是 HashSet 的子类
  • LinkedHashSet 依据成分的 hashCode
    值来控制成分的贮存地方,但它同时使用链表维护成分的次第,那使得成分看起来是以插入顺序保存的。
  • LinkedHashSet插入品质略低于 HashSet,但在迭代作客 Set
    里的成套因素时有很好的习性。
  • LinkedHashSet 不允许集合成分重复。

代码示例

Set<String> set = new LinkedHashSet<String>();// ctrl+shift+O
set.add("one");
set.add("two");
set.add("three");
set.add("four");
set.add("four");
/*
 * for(int i=0;i<set.size();i++){ set. }
 */
System.out.println("长度:" + set.size());

Iterator<String> it = set.iterator();

while (it.hasNext()) {
    System.out.println(it.next());
}

出口结果:

长度:4
one
four
two
three
public static native int identityHashCode(Object x);

图片 3

Set完成类之三 TreeSet

  • TreeSet 是 SortedSet 接口的完结类,TreeSet
    能够保证集合成分处于排序状态。
  • Comparator comparator()
  • Object first()
  • Object last()
  • Object lower(Object e)
  • Object higher(Object e)
  • SortedSet subSet(fromElement, toElement)
  • SortedSet headSet(toElement)
  • SortedSet tailSet(fromElement)
  • TreeSet 两种排序方法:自然排序和定制排序。私下认可境况下,TreeSet
    选择自然排序。

案例5

public static void main(String[] args) {
    //创建对象
    TreeSet<String> set = new TreeSet<String>();
    //添加数据
    set.add("f");
    set.add("y");
    set.add("A");
    set.add("Z");
    System.out.println("长度   "+set.size());
    System.out.println("第一个元素:"+set.first());
    System.out.println("最后个元素:"+set.last());
    System.out.println("--------------------");
    Iterator<String> it = set.iterator();
    while(it.hasNext()){
        System.out.println(it.next());
    }
}

输出结果:

长度   4
第一个元素:A
最后个元素:y
--------------------
A
Z
f
y   

本来排序

  • 当然排序:TreeSet 会调用集合成分的 compareTo(Object obj)
    方法来相比成分之间的轻重缓急关系,然后将集合成分按升序排列
  • 要是打算把一个对象添加到 TreeSet 时,则该目的的类必须实现 Comparable
    接口。

  • 福寿齐天 Comparable 的类必须兑现 compareTo(Object obj)
    方法,七个目的即经过 compareTo(Object obj) 方法的重临值来相比大小。

  • Comparable 的优良完毕:

  • BigDecimal、BigInteger
    以及具有的数值型对应的包装类:按它们对应的数值大小实行比较
  • Character:按字符的 unicode值来进展相比
  • Boolean:true 对应的包裹类实例大于 false 对应的包裹类实例
  • String:按字符串中字符的 unicode 值实行相比
  • Date、Time:前面包车型客车光阴、日期比前面包车型大巴光阴、日期大

  • 向 TreeSet
    中添日币素时,唯有首先个成分无须相比较compareTo()方法,前面添加的具备因素都会调用compareTo()方法开展比较。
  • 因为唯有相同类的多个实例才会比较大小,所以向 TreeSet
    中拉长的应当是同一个类的指标
  • 对于 TreeSet
    集合而言,它判断多少个指标是还是不是等于的唯一标准是:四个对象通过
    compareTo(Object obj) 方法比较再次回到值
  • 当须求把贰个目的放入 TreeSet 中,重写该指标对应的 equals()
    方法时,应保障该方法与 compareTo(Object obj)
    方法有雷同的结果:若是八个指标通过 equals() 方法相比较再次来到true,则透过 compareTo(Object obj) 方法比较应重回 0

定制排序

  • TreeSet的当然排序是依据集合成分的高低,进行成分升序排列。借使急需定制排序,比如降序排列,可透过Comparator接口的支持。供给重写compare(T
    o1,T o2)方法。
  • 选取int compare(T o1,T
    o2)方法,相比o1和o2的高低:如果艺术重回正整数,则意味着o1大于o2;若是重回0,表示非凡;重返负整数,表示o1稍低于o2。
  • 要促成定制排序,必要将促成Comparator接口的实例作为形参传递给TreeSet的构造器。
  • 那儿,还是只能向TreeSet中添加类型相同的靶子。不然发生ClassCastException格外。
  • 选用定制排序判断多少个要素相等的正经是:通过Comparator比较三个成分重临了0。

意料之中,也是native方法。那几个办法再次回到的结果也是基于目的的地点转换而来的,与Object的实例调用hashCode()再次回到的结果同样(前提是hashCode()方法未被子类重写)。

图片 4

Set和List区别

  • Set中的成分不能够重新
  • 接近数学中汇聚的概念,成分是绝无仅有的
  • 怎么称呼重复?
  • List中的成分允许再一次
  • 隐含地有个顺序关系
  • 支持ListIterator迭代器,能回溯

汇聚的力量:

并集
boolean addAll(Collection collectionToAdd)
差集
boolean removeAll(Collection collectionToAdd)
交集
boolean retainAll(Collection collectionToAdd)

代码示例

public static void main(String[] args) {
    Set set1=new HashSet();
    set1.add(new Date());    //向列表中添加数据
    set1.add("apple");     //向列表中添加数据
    set1.add(new Integer(3));   //向列表中添加数据
    set1.add(new Socket());    //向列表中添加数据
    int size=set1.size();
    System.out.println("Set1集合的大小为:" + size);
    Set set2=new HashSet();
    set2.add("book");     //向列表中添加数据
    set2.add(new Long(3));    //向列表中添加数据
    int size2=set2.size();
    System.out.println("Set2集合的大小为:" + size2);
    set1.addAll(set2);
    System.out.println("合并后Set1集合的大小为:" + set1.size());
    set1.removeAll(set2);
    System.out.println("拆分后Set1集合的大小为: " + set1.size());
    set1.retainAll(set2);
    System.out.println("Set1和Set2集合交集的部分:" + set1.size());
}   

出口结果:

Set1集合的大小为:4
Set2集合的大小为:2
合并后Set1集合的大小为:6
拆分后Set1集合的大小为: 4
Set1和Set2集合交集的部分:2

列表的力量:

在钦命的地点插入
void add(int index, Obeject newElement)
收获有个别索引的成分
Object get(int index)
设置有个别索引的要素
Object set(int index, Object newElement)
删去某些索引的因素
Object remove(int index)

代码示例

class Persons{

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

    Persons(){

    }
    Persons(String name){
        this.name = name;
    }

    public static void main(String[] args) {
        List<Persons> persons  = new ArrayList<Persons>();
        persons.add(new Persons("张三"));
        persons.add(new Persons("李四"));
        persons.add(new Persons("王五"));
        persons.add(new Persons("赵六"));

        System.out.println(persons.get(0).getName());//这里仅作输出查看
        persons.set(1,new Persons("赵六"));
        persons.remove(2);

        for(Persons person: persons){
            System.out.println(person.getName());
        }
    }
}

输出结果:

get方法:张三
张三
赵六
赵六

唯独依然有点小差别,就是在处理null值的时候:

Collection 接口

3.3.3 Map接口

  • Map与Collection并列存在。用于保存具有映射关系的数额:Key-Value
  • Map 中的 key 和 value 都得以是其它引用类型的数量
  • Map 中的 key 用Set来存放在,不允许再一次,即同三个 Map
    对象所对应的类,须重写hashCode()和equals()方法。
  • 常用String类作为Map的“键”。
  • key 和 value 之间存在单向一对一涉嫌,即通过点名的 key
    总能找到唯一的、鲜明的 value。

Map种类继承树

图片 5

System.identityHashCode(null)会重临0,而针对null的Object对象调用hashCode()明显会产出NPE分外。

·Collection接口是List、Set和Queue接口的父接口,该接口里定义的措施既可用于操作Set集合,也可用来操作List和Queue集合。

3.3.3.1 Map常用艺术

  • 增进、删除操作:

  • Object put(Object key,Object value)

  • Object remove(Object key)

  • void putAll(Map t)

  • void clear()

  • 元视图操作的点子:

  • Set keySet()

  • Collection values()

  • Set entrySet()

  • 要素查询的操作:

  • Object get(Object key)

  • boolean containsKey(Object key)

  • boolean containsValue(Object value)

  • int size()

  • boolean isEmpty()

  • boolean equals(Object obj)

package com.prac;
public class Obj {
    public static void main(String[] args) {
        Obj obj = null;
//        System.out.println(obj.hashCode());//NPE异常
        System.out.println(System.identityHashCode(null));//0
    }
}

·JDK不提供此接口的其他直接促成,而是提供更具体的子接口(如:Set和List)完成。

3.3.3.2 Map落成类之一 HashMap

  • Map接口的常用完结类:HashMap、TreeMap和Properties。
  • HashMap是 Map 接口使用频率最高的落到实处类。
  • 同意选用null键和null值,与HashSet一样,不保障映射的次第。
  • HashMap 判断五个 key 相等的正规化是:四个 key 通过 equals() 方法重临true,hashCode 值也约等于。
  • HashMap 判断四个 value相等的专业是:七个 value 通过 equals()
    方法重临 true。

除此以外,由于数组木有重写Object的hashCode()方法,由此任何数组对象调用hashCode()方法取得的都以依据对象地址总计出来的值,也便是与System.identityHashCode()格局调用重临的结果一致。

·在Java5事先,Java集合会丢失容器中指标的数据类型

3.3.3.3 Map完成类之二 LinkedHashMap

  • LinkedHashMap 是 HashMap 的子类
  • 与LinkedHashSet类似,LinkedHashMap 能够爱戴 Map
    的迭代顺序:迭代相继与 Key-Value 对的插入顺序一致

实验一下:

Collection接口方法

3.3.3.4 Map实现类之三 TreeMap

  • TreeMap存款和储蓄 Key-Value 对时,须要依据 key-value 对进展排序。TreeMap
    能够确定保障全体的 Key-Value 对处于平稳状态。
  • TreeMap 的 Key 的排序:

  • 本来排序:TreeMap 的持有的 Key 必须兑现 Comparable 接口,而且具有的
    Key 应该是同2个类的目的,不然将会抛出 ClasssCastException
  • 定制排序:创造 TreeMap 时,传入1个 Comparator 对象,该目的承担对
    TreeMap 中的全部 key 实行排序。此时不必要 Map 的 Key 完成 Comparable
    接口

  • TreeMap判断八个key相等的正儿八经:三个key通过compareTo()方法大概compare()方法再次回到0。
  • 若选拔自定义类作为TreeMap的key,所属类需求重写equals()和hashCode()方法,且equals()方法重返true时,compareTo()方法应再次来到0。

案例6

package day07;

import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;

class Code implements Comparable<Code> {

    private int id;

    public Code(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        if (obj instanceof Code) {
            Code c = (Code) obj;

            if (c.id == this.id) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return id;
    }

    @Override
    public String toString() {
        return "Code [id=" + id + "]";
    }

    @Override
    public int compareTo(Code o) {
        if (this.id > o.id) {
            return 1;
        } else if (this.id < o.id) {
            return -1;
        } else {
            return 0;
        }
    }
}

class Person1 {

    private Code id;// 身份

    private String name;// 姓名

    public Person1(String name, Code id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public Code getId() {
        return id;
    }

    @Override
    public String toString() {
        return "Person1 [id=" + id + ", name=" + name + "]";
    }
}

public class Treemap {

    public static void main(String[] args) {

        // Comparable 与Comparator
        TreeMap<Code, Person1> map = new TreeMap<Code, Person1>();

        // 购物车 Map

        Person1 p1 = new Person1("张三", new Code(1111));
        Person1 p2 = new Person1("李四", new Code(1112));
        Person1 p3 = new Person1("王五", new Code(1113));
        Person1 p4 = new Person1("赵六", new Code(1114));

        Person1 p5 = new Person1("周七", new Code(1111));

        map.put(p1.getId(), p1);
        map.put(p2.getId(), p2);
        map.put(p3.getId(), p3);
        map.put(p4.getId(), p4);
        map.put(p5.getId(), p5);

        System.out.println("长度" + map.size());

        Set<Entry<Code, Person1>> set = map.entrySet();

        Iterator<Entry<Code, Person1>> it = set.iterator();
        while (it.hasNext()) {
            Entry<Code, Person1> entry = it.next();

            Person1 p = entry.getValue();
            System.out.println(p.getId() + "---" + p.getName());
        }

        Person1 p = map.get(new Code(1111));
        System.out.println("xxxxxx" + p);

    }
}

出口结果:

长度4
Code [id=1111]---周七
Code [id=1112]---李四
Code [id=1113]---王五
Code [id=1114]---赵六
xxxxxxPerson1 [id=Code [id=1111], name=周七]
        int[] ary = new int[10];
        System.out.println(ary.hashCode());
        System.out.println(System.identityHashCode(ary));

图片 6

3.3.3.4 Map实现类之四 Hashtable

  • Hashtable是个古老的 Map 达成类,线程安全。
  • 与HashMap不相同,Hashtable 差异意利用 null 作为 key 和 value
  • 与HashMap一样,Hashtable 也不能确定保障内部 Key-Value 对的相继
  • Hashtable判断几个key相等、七个value相等的行业内部,与hashMap一致。

输出:

图片 7

HashMap和Hashtable的区别

一.历史由来:Hashtable是遵照陈旧的Dictionary类的,HashMap是Java
1.2推荐的Map接口的二个贯彻

二.同步性:Hashtable是线程安全的,也正是说是一路的,而HashMap是线程序不安全的,不是一只的

三.值:唯有HashMap可以让你将空值作为3个表的条指标key或value

778966024
778966024

接纳Iterator接口遍历集合成分

3.3.3.5 Map完毕类之五 Properties


  • Properties 类是 Hashtable 的子类,该目标用于拍卖属性文件
  • 鉴于品质文件里的 key、value 都是字符串类型,所以 Properties 里的 key
    和 value 都以字符串类型
  • 存取数据时,提出采取setProperty(String key,String
    value)方法和getProperty(String key)方法

代码示例

import java.util.Iterator;
import java.util.Properties;
import java.util.Set;

public class PropertiesDemo {

    public static void main(String[] args) {
        new PropertiesDemo();
        Properties pro = new Properties();
        pro.put("name", "root");
        pro.put("pass", "root");
        pro.put("url", "jdbc:mysql://localhost:3306/db");
        String name = pro.getProperty("name");
        System.out.println(name);
        // 遍历
        /*Set<Object> set = pro.keySet();

        Iterator<Object> it = set.iterator();

        while (it.hasNext()) {
            System.out.println(pro.get(it.next()));
        }*/
        Set<String> set = pro.stringPropertyNames();
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            System.out.println(pro.get(it.next()));
        }
    }

}

输出结果:

root
root
jdbc:mysql://localhost:3306/db
root

而是,常获取数据库密码链接等是经过外部文件得到

{
    Properties pro = new Properties();
    try {
        InputStream is = getClass().getResourceAsStream("jdbc.properties");
        pro.load(is);
        System.out.println("user=="+pro.get("user"));
        System.out.println("password=="+pro.get("password"));
        System.out.println("url==="+pro.get("url"));
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

 以上依据目的地址来计算hashCode值是比较”原始简单狂暴”的方针。二个对象自笔者的始末(属性数据)改变后,其hashCode仍旧不会变,例如上边这一个事例。在诸多实在运用场景中,那说不定不是叁个很好的方针。姑且将那种政策称之为“base
on address”,实际上那与前面要介绍的“base on content”形成1个比对效果。

·Iterator对象称为迭代器(设计情势的一种),首要用来遍历Collection集合中的成分。

3.3.4 操纵集合的工具类 Collections

  • Collections 是一个操作 Set、List 和 Map 等联谊的工具类
  • Collections
    中提供了一文山会海静态的主意对集合成分举办排序、查询和改动等操作,还提供了对聚集对象设置不可变、对聚集对象实现同步控制等格局
  • 排序操作:(均为static方法)

  • reverse(List):反转 List 中成分的依次
  • shuffle(List):对 List 集合成分进行任意排序
  • sort(List):依据成分的本来顺序对点名 List 集合成分按升序排序
  • sort(List,Comparator):依据钦赐的 Comparator 发生的次第对 List
    集合成分实行排序
  • swap(List,int, int):将钦赐 list 集合中的 i 处成分和 j
    处成分进行置换

查找、替换

  • Object max(Collection):依照成分的自然顺序,返回给定集合中的最大因素
  • Object max(Collection,Comparator):根据 Comparator
    内定的各种,再次来到给定集合中的最大要素
  • Object min(Collection)
  • Object min(Collection,Comparator)
  • int frequency(Collection,Object):再次回到钦命集合中钦赐成分的面世次数
  • void copy(List dest,List src):将src中的内容复制到dest中
  • boolean replaceAll(List list,Object oldVal,Object
    newVal):使用新值替换 List 对象的保有旧值

同步控制

Collections 类中提供了七个 synchronizedXxx()
方法,该措施可使将点名集合打包成线程同步的聚众,从而能够消除多线程并发访问集合时的线程安全题材

图片 8

        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        System.out.println(System.identityHashCode(list));//1794515827
        list.add(2);
        System.out.println(System.identityHashCode(list));//1794515827,与改变前的hashCode一样,因为对象地址没变

·全体实现了Collection接口的集合类都有一个Iterator()方法,用于重临2个贯彻了Iterator接口的靶子。

3.3.4.1 Collection和Collections区别

Collections是个java.util下的类,它蕴涵有各类有关集合操作的静态方法。

Collection是个java.util下的接口,它是种种集合结构的父接口。

 

·Iterator仅用于遍历集合,Iterator本身并不提供承装对象的能力。倘使急需制造Iterator对象,则必须有三个被迭代的成团。

3.3.5 Enumeration

Enumeration 接口是 Iterator 迭代器的 “古老版本”

图片 9

案例7

Enumeration stringEnum = new StringTokenizer("a-b*c-d-e-g", "-");
while(stringEnum.hasMoreElements()){
    Object obj = stringEnum.nextElement();
    System.out.println(obj); 
}

出口结果:

a
b*c
d
e
g

贰 、邂逅基本包装档次

Iterator接口的法子

 2.1、Integer类型的hashCode实现

图片 10

Integer当然也重写了其直接父类Object的hashCode()方法,在JDK1.8从前,是直接回到Integer对象的数值value,JDK1.第88中学增多了三个静态方法,通过调用静态方法也是直接重回对象的数值value。

在调用it.next()方法此前必需求调用it.hasNext()举行检查和测试。若不调用,且下一条记下无效,直接调用it.next()会抛出NoSuchElementException万分。

    @Override
    public int hashCode() {
        return Integer.hashCode(value);
    }
    /**
     * @since 1.8
     */
    public static int hashCode(int value) {
        return value;
    }

·Java 5提供了foreach循环迭代走访Collection

2.2、Long类型的hashCode实现

for(Person(类型) p(遍历后成分名称):persons(要遍历的会合名称)){

Long是将其值实行无符号右移3二人的结果在与其本人做异或运算,最终回来二个int值,嗯,好像有个别看头!

      p.getName();

    @Override
    public int hashCode() {
        return Long.hashCode(value);
    }
    /**
     * @since 1.8
     */
    public static int hashCode(long value) {
        return (int)(value ^ (value >>> 32));
    }

}

 

List接口

3.2、Character、Short和Byte

·java中数组用来储存数据的局限性

Character类型、Short类型和Byte类型基本是运用相同的法子,都以将char、short或然byte类型向上转型为int类型,就直接回到了,不一一列举。

·List集合类中成分有序、且可再度,集合中的各样成分都有其对应的顺序索引。

以Character为例:

·List容器中成分都对应三个平头型的序号存取容器中成分。

    @Override
    public int hashCode() {
        return Character.hashCode(value);
    }
    /**
     * @since 1.8
     */
    public static int hashCode(char value) {
        return (int)value;
    }

·JDK API中LIst接口的实现类常用的有:ArrayList、LinkedList和Vector。

 

·List集合里添加了部分依照索引来操作集合成分的措施

3.3、Float和Double的hashCode实现

  void add(int index, Object ele)

那五个品类的落到实处差不离相比相近,可是有个别有点糟糕驾驭。

  boolean addAll(int index, Collection eles)

此间以Float为例,Float类(>=JDK1.8)中求解hashCode进度中分头调用了如下的方法。

  Object get(int index)

    @Override
    public int hashCode() {
        return Float.hashCode(value);
    }
    /**
     * @since 1.8
     */
    public static int hashCode(float value) {
        return floatToIntBits(value);
    }
    public static int floatToIntBits(float value) {
        int result = floatToRawIntBits(value);
        // Check for NaN based on values of bit fields, maximum
        // exponent and nonzero significand.
        if ( ((result & FloatConsts.EXP_BIT_MASK) ==
              FloatConsts.EXP_BIT_MASK) &&
             (result & FloatConsts.SIGNIF_BIT_MASK) != 0)
            result = 0x7fc00000;
        return result;
    }
    public static native int floatToRawIntBits(float value);

  int indexOf(Object obj)

看得出最终是调用floatToRawIntBits()方法,有点意思!

  int lastIndexOf(Object obj)

以此floatToRawIntBits()方法的官方申明是:

  Object remove(int index)

Returns a representation of
the specified floating-point value according to the IEEE 754
floating-point “single format” bit layout, preserving Not-a-Number
(NaN) values.

  Object set(int index, Object ele)

本身个人知道正是将该浮点数在IEEE
754正经下的二进制位表示一贯当成int类型的二进制位来分解,约等于忽视掉IEEE
754专业的预订规则。API的法子命名floatToIntBits也差不离是想发挥这一个语义吧。

  List subList(int fromIndex, int toIndex)

IEEE
754正经表示33人浮点数格式分三片段:数符S(第贰九人),阶码E(第③二人-30人共陆位)和尾数M(剩下的2四位)。

List达成类之一:ArrayList

切切实实的求解进程举个栗子:

·ArrayList是List接口的第一名实现类

或然以经典的浮点数Float valuef = 100.25f为例,IEEE 754正经表示经过如下:

·本质上,ArrayList是目的引用的三个变长数组
·ArrayList是线程不安全的,而Vector是线程安全的,固然为确定保证List集合线程安全也不引进使用Vector

图片 11

List完结类之二:LinkedList

三十二人的二进制:0100 0010 1100 一千 1000 0000 0000 0000理所当然是遵照IEEE
754行业内部表示的结果,可是计算hashCode时直接将那么些二进制数遵照int类型来诠释正是1120436224。

·对于频繁的插入或删除成分的操作,建议选取LinkedList类,效能较高

所以valuef 的hashCode应该是1120436224。

·新增方法:

尝试一下:

  void addFirst(Object obj)

        Float valuef = 100.25f;
        System.out.println("hashCode = "+valuef.hashCode());
        System.out.println("floatToIntBits = "+Float.floatToIntBits(valuef));
        System.out.println("floatToRawIntBits = "+Float.floatToRawIntBits(valuef));
        System.out.println("0x42C88000->decimal = "+Integer.parseInt("0x42C88000".substring(2),16));
        System.out.println(Float.toHexString(new Float(100.25f)));

  void addLast(Object obj) 

输出:

  Object getFirst()

hashCode = 1120436224
floatToIntBits = 1120436224
floatToRawIntBits = 1120436224
0x42C88000->decimal = 1120436224
0x1.91p6

  Object getLast()

Double类求hashCode与Float原理是近似的。

  Object removeFirst()

3.4、Boolean类型的hashCode实现

  Object removeLast()

Boolean类型的hashCode最搞笑了,根据Boolean对象的值进行双边其选一:true->1231,false->1237。为何程序的完结者会选取这八个值作为其hashCode呢,有啥样传说啊?不造也!大概即便小编个人癖好?

Set接口

    @Override
    public int hashCode() {
        return Boolean.hashCode(value);
    }
    /**
     * @since 1.8
     */
    public static int hashCode(boolean value) {
        return value ? 1231 : 1237;
    }

·Set接口是Collection的子接口,set接口没有提供额外的办法

 

·Set集合不允许包括相同的要素,要是试把四个一律的因素参与同二个Set集合中,则增加操作战败。

三 、拐角遇见String类

·Set判断四个对象是还是不是一律不是使用==运算符,而是依照equals方法。

String类重写了父类Object的hashCode()方法:

 

    /**
    *===================================================================
    * String当然是重写了Object的hashCode()方法
    * hashCode的生成逻辑:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
    * 空字符串的hashCode是0
    *==================================================================
    */
    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;
            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

Set达成类之一:HashSet

 如若从数学角度来直观的表现那一个求解进程,大约是下边那样的:

·HashSet是Set接口的非凡达成,大部分时候利用Set集合时都施用那么些完成类。

图片 12

·HashSet按Hash算法来储存集合中的成分,因而全部很好的存取和摸索品质。

化简一下求解进度也很简短:将前方n-3个等式的左右两边依次乘上31^(n-1)、31^(n-1)…31^贰 、31,再左右增进就可以错位相消。n次迭代后,hashCode计算由如下公式的付出:

·HashSet具有以下特点:

 图片 13

  无法担保元素的排列顺序

本来那里的hashCode很有恐怕因为超越-1>>>1而溢出重临叁个负数。

  HashSet不是线程安全的

素数31在后边的其余hashCode方法中都很宽泛,就像是是多少个所谓的“Mason素数”,没研讨过,选31也恐怕是考虑用移动运算(1<<5)-1相比较快吧。

  集合元素能够是null

 肆 、眼看他起朱楼

·当向 HashSet 集合中存入二个成分时,HashSet 会调用该目标的 hashCode()
方法来获取该指标的 hashCode 值,然后依照 hashCode 值决定该对象在 HashSet
中的存款和储蓄地点。

有了上述的String和8种骨干包装档次的hashCode完成,其余类的hashCode基本上正是在其面前的功底上做扩充,做迭代。

·HashSet集合判断三个因素相等的标准:八个指标通过hashCode()方法比较相等,并且八个对象的equals()方法重临值也也等于。

比如说:工具类Arrays中,求二个long类型的数组的hashCode,正是将每一种成分值的hashCode遵照规则进行n次迭代,其源码如下:

hashCode()方法

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

        int result = 1;
        for (long element : a) {
            int elementHash = (int)(element ^ (element >>> 32));
            result = 31 * result + elementHash;
        }
        return result;
    }

·如若四个因素的equals()方法再次来到true,但它们的hashCode()重临值不对等,HashSet将会把它们存款和储蓄在不一致的任务,但还是可以增加成功。

Arrays类针对差异的参数(byte[],int[],long[]等等)重载了许多hashCode()方法,基本都以比照此思路来迭代求解hashCode值的。 

·对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object
obj)方法,以贯彻目的相等规则。

那些迭代可以有二个通用公式:

·重写hashCode()方法的中央原则

图片 14

  在程序运维时,同多少个对象往往调用hashCode()方法应该回到相同的值

实际上,“将种种成分值的hashCode依照规则举办n次迭代”那样的落到实处有肯定的考证。Arrays中的这么些办法都服从一个所谓的“based
on the
contents”的准绳,即那一个再次回到的hashCdoe只与数组中的成分自个儿有关,跟那几个数组对象的地点毫无干系。

  当五个目的的equals()方法相比重返true时,那七个目的的hashCode()方法的再次来到值也应有对等

举个栗子很简单验证:

  对象中用作equals()方法相比较的Field,都应有用来测算hashCode值

        int[] aryA = {1,2,3};
        int[] aryB = {1,2,3};
        System.out.println("AryA ?= AryB : "+(aryA == aryB));
        System.out.println(Arrays.hashCode(aryA));//30817
        System.out.println(Arrays.hashCode(aryB));//30817,aryA和aryB显然是两个不同的对象,但是它们的"内容"相同

Set达成类之二:LinkedHsahSet

输出:

·LinkedHashSet是HashSet的子类

AryA ?= AryB : false
30817
30817

·LinkedHashSet依据元素的hashCode值来控制成分的积存位置,但它同时选用链表维护成分的主次,那使得成分看起来是以插入顺序保存的。

 

·LinkedHashSet插入质量略低于HashSet,但在迭代拜会Set里的全部成分时由很好的习性。

除此以外,针对对象数组,Arrays中提供五个法子来求解其hashCode:hashCode(Object
a[])和deepHashCode(Object a[])

·LinkedHashSet差别意集合成分重复。

 第二个主意能够了解为只完毕了一层“基于内容”(based on the
contents)的调用,当指标数组中的成分照旧三个数组时(也即多维数组),第三层实际上是依照数组对象地址来生成hashCode,那有点有点违背了“based
on the contents”原则。这些层面来讲,这是种“浅迭代”的点子。

Set完毕类之三:TreeSet

想要严苛的完成“基于内容”,能够透过第3个形式deepHashCode(Object
a[]),该办法在每一层迭代时会对每2个成分举行项目校验,以保障该因素都以主导项目标数组,假若不是,就再而三递归下去。那样实在完毕了“based
on the contents”。

·TreeSet是SortedSet接口的兑现类,TreeSet可以有限帮忙集合成分处于排序状态

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

        int result = 1;

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

        return result;
    }

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

        int result = 1;

        for (Object element : a) {
            int elementHash = 0;
            if (element instanceof Object[])
                elementHash = deepHashCode((Object[]) element);
            else if (element instanceof byte[])
                elementHash = hashCode((byte[]) element);
            else if (element instanceof short[])
                elementHash = hashCode((short[]) element);
            else if (element instanceof int[])
                elementHash = hashCode((int[]) element);
            else if (element instanceof long[])
                elementHash = hashCode((long[]) element);
            else if (element instanceof char[])
                elementHash = hashCode((char[]) element);
            else if (element instanceof float[])
                elementHash = hashCode((float[]) element);
            else if (element instanceof double[])
                elementHash = hashCode((double[]) element);
            else if (element instanceof boolean[])
                elementHash = hashCode((boolean[]) element);
            else if (element != null)
                elementHash = element.hashCode();

            result = 31 * result + elementHash;
        }

        return result;
    }

   Comparator comparator()

 

   Object first()

其它的像Objects类(Object的工具类,也是null值包容的),以及汇集对象(在它们的说梅止渴父类:AbstractList,AbstractMap,AbstractSet等中贯彻了hashCode()方法)差不离都以鲁人持竿Arrays中的完结思路来完毕的,而且也都遵循”based
on the contents”这一为主原则。

   Object last()

        int[] aryA = {1,2,3};
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(2);
        list.add(3);
        System.out.println(Arrays.hashCode(aryA));//30817
        System.out.println(list.hashCode());//30817

   Object lower(Object e)

 五、结局了,散了吧

   Object higher(Object e)

大结局了,依然简单看看一下HashMap中的hashCode完结,本来HashMap没有怎么特殊性的。

   SortedSet subSet(fromElement, toElement)

确切的说那里说的是HashMap中的节点成分Node的hashCode达成。

   SortedSet headSet(toElement)

因为HashMap内部实际上是用了贰个Node<K,V>类型的数组来存款和储蓄HashMap对象的有效性数据,Node对象中分头有几个属性:hash,kye,value以及针对下八个Node对象的next。大概可以用如下图那样来精通:

   SortedSet tailSet(fromElement)

图片 15

·TreeSet 二种排序方法:自然排序和定制排序。暗中同意情形下,TreeSet
选拔自然排序。

在那之中间类Node的hashCode()达成:

排序–自然排序

    static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;
        final K key;
        V value;
        Node<K,V> next;

        //其他如构造器,getter方法略掉
        public final int hashCode() {
            return Objects.hashCode(key) ^ Objects.hashCode(value);
        }
        //其他方法略掉
    }

·自然排序:TreeSet 会调用集合成分的 compareTo(Object obj)
方法来比较成分之间的大小关系,然后将集合成分按升序排列

本条hashCode实现多少欲言又止,在源码中就像是从未见到那一个Node的hashCode()方法的调用?

·假诺准备把一个对象添加到 TreeSet 时,则该目的的类必须兑现 Comparable
接口。

在JDK1.第88中学的HashMap对象调用put方法中hash值是应用如下格局生成:

  达成 Comparable 的类必须贯彻 compareTo(Object obj)
方法,八个目的即经过 compareTo(Object obj) 方法的重返值来相比大小。

    static final int hash(Object key) {
        int h;
        return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    }

·Comparable 的天下第贰达成:

从而HashMap的hash值也是站在前边的肩头上的。

  BigDecimal、BigInteger
以及具有的数值型对应的包装类:按它们对应的数值大小实行比较

 

  Character:按字符的 unicode值来拓展相比

全剧终!

  Boolean:true 对应的卷入类实例大于 false 对应的包裹类实例

尔后hashCode和程序员过上了甜蜜美满的活着!

  String:按字符串中字符的 unicode 值举办相比较

 

  Date、Time:前面包车型地铁时光、日期比前边的年华、日期大

·向 TreeSet
中添欧成分时,唯有首先个要素无须相比compareTo()方法,前面添加的具备因素都会调用compareTo()方法举行相比。

·因为只有相同类的四个实例才会比较大小,所以向 TreeSet
中丰硕的应当是同1个类的对象

·对于 TreeSet 集合而言,它判断七个目的是或不是等于的唯一标准是:多少个目的通过
compareTo(Object obj) 方法比较再次来到值

·当须求把贰个指标放入 TreeSet 中,重写该对象对应的 equals()
方法时,应确认保证该方法与 compareTo(Object obj)
方法有一致的结果:借使多个目标通过 equals() 方法比较重返 true,则通过
compareTo(Object obj) 方法比较应再次来到 0

·TreeSet的当然排序是依据集合成分的轻重,举办成分升序排列。假若供给定制排序,比如降序排列,可透过Comparator接口的助手。需求重写compare(T
o1,T o2)方法。

·利用int compare(T o1,T
o2)方法,相比o1和o2的尺寸:就算措施重返正整数,则代表o1大于o2;借使重临0,表示卓殊;再次来到负整数,表示o1稍差于o2。

·要贯彻定制排序,须求将完结Comparator接口的实例作为形参传递给TreeSet的构造器。

·此时,还是只好向TreeSet中添加类型相同的指标。不然产生ClassCastException十分。

·使用定制排序判断多个要素相等的标准是:通过Comparator相比四个因素再次回到了0。

 

Map接口

·Map与Collection并列存在。用于保存具有;映射关系的数据:Key-Value

·Map中的Key和value都足以是其余引用类型的多寡

·Map中的key用Set来存放,不容许再一次,即同二个Map对象所对应的类,须重写hashCode()和equals()方法。

·常用String类作为Map的“键”

·key和value之间存在单向一对一涉及,即经过制订的key总能找到唯一的、显明的value。

Map常用艺术

·添加、删除操作:

Object put(Object key,Object value)

Object remove(Object key)

void putAll(Map t)

void clear()

·元视图操作的点子:

Set keySet()

Collection values()

Set entrySet()

·成分查询的操作:

Object get(Object key)

boolean containsKey(Object key)

boolean containsValue(Object value)

int size()

boolean isEmpty()

boolean equals(Object obj)

Map完毕类之一:HashMap

·Map接口的常用达成类:HashMap、TreeSet和Properties。

·HashMap是Map接口使用频率最高的兑现类。

·允许利用null键和null值,与HashSet一样,不保证映射的相继

·HashMap判断三个key相等的正儿八经是:三个Key通过equals()方法重返true,hashCode值也相当于。

·HashMap判断七个value相等的标准是: 四个value通过equals()方法重临true。

Map实现类之二:LinkedHashMap

·LinkedHashMap是HashMap的子类

·与LinkedHashSet类似,LinkedHashMap能够爱戴Map的迭代顺序:迭代相继:迭代逐一与Key-Value对的插入顺序一致

Map完成类之三:TreeMap

·TreeMap存款和储蓄Key-Value对时,必要依照Key-value对拓展排序。TreeMap能够确定保证全部的Key-Value对处于平稳状态。

·TreeMap的Key的排序:

  自然排序:TreeMap的保有Key必须兑现comparable接口,而且具有的Key应该是同七个类的对象,不然将会抛出ClassCastException

  定制排序:创立TreeMap时,传入二个comparator对象,该对象承担对TreeMap中的全部key进行排序。此时不须要Map的Key达成Comparable接口

·TreeMap判断八个key相等的规范:五个key通过compareTo()方法依旧compare()方法重回0.

·若使用自定义类作为TreeMap的Key,所属类需求重写equals()和hashCode()方法,且eqauls()重回true时,compareTo()方法应再次来到0。

Map实现类之四:hashtable

·Hashtable是个古老的Map实现类,线程安全。

·HashMap不一样,Hashtable不允许使用null作为key和value

·与HashMap一样,Hashtable也不可能担保内部Key-Value对的各种

Hashtable判断多个key相等、三个value相等的正儿八经,与HashMap一贯。

Map达成类之五:Properties

·Properties类是Hashtable的子类,该对象用于拍卖属性文件

·由于质量文件里的key、value都是字符串类型,所以Properties里的key和value都是字符串类型。

·存取数据时,建议利用setProperty(String key,String
value)方法和getProperty(String key)方法

 

 

例:

Properties pros = new Properties();

pros.load(new FileInputStream(“jdbc.properties”));

String user = pros.getProperty(“user”);

System.out.println(user);

 

操作集合的工具类:Collections

操作数组的工具类:Arrays

·Collections是3个操作Set、List和Map等集合的工具类

·Collection中提供了一多如牛毛静态的法门对集合成分进行排序、查询和改动等操作,还提供了对聚集对象设置不可变、对聚集对象实现同步控制等措施。

·排序操作:(均为static方法)

  reverse(List):反转List中成分的顺序

  shuffle(List):对List集合成分进行随机排序

  sort(List):依据成分的当然顺序对内定List集合成分按升序排序

  sort(List,Comparator):依照内定的Compareator爆发的顺序对List集合成分进行排序

  swap(List,int,int):将钦命list集合中的i处成分和j处成分举办置换

·Object
max(Collection):依照成分的自然顺序,重返给钦定集合中的最大要素

·Object
max(Collection,Comparator):依据Comparator钦命的一一,重回给定集合中的最大因素

·Object min(Collection)

·Object min(Collection,Comparator)

·int frequency(Collection,Object):重返钦点集合中内定成分的产出次数

·void copy(List dest,List src):将src中的内容复制到dest中

·boolean replaceAll(List list,Object oldVal,Object
newVal):使用新值替换List对象的兼具旧值

同步控制

·Collections 类中提供了四个 synchronizedXxx()
方法,该方法可使将点名集合打包成线程同步的集结,从而能够缓解多线程并发访问集合时的线程安全题材

相关文章