一、Java集合框架概述

●一方面,面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另一方面,使用Array存储对象方面具有一些弊端,而Java集合就像一种容器,可以动态地把多个对象的引用放入容器中。

?数组在内存存储方面的特点:

数组初始化以后,长度就确定了。

数组声明的类型,就决定了进行元素初始化时的类型

?数组在存储数据方面的弊端:

数组初始化以后,长度就不可变了,不便于扩展

数组中提供的属性和方法少,不便于进行添加、删除、插入等操作,且效率不高。同时无法直接获取存储元素的个数

数组存储的数据是有序的、可以重复的。--->存储数据的特点单一

●Java集合类可以用于存储数量不等的多个对象,还可用于保存具有映射关系的关联数组。

二、集合框架

●Java集合可分为Collection和Map两种体系

?Collection接口:单列数据,定义了存取一组对象的方法的集合

List:元素有序、可重复的集合 --> “动态”数组

ArrayList、LinkedList、Vector

Set: 元素无序、不可重复的集合

HashSet、LinkedHashSet、TreeSet

?Map接口:双列数据,保存具有映射关系“key-value对”的集合

HashMap、LinkedHashMap、TreeMap、Hashtable、Properties

Collection接口继承树

Map接口继承树

三、Collection接口

1.Collection接口常用的15种方法

package com.xudong.java;

import org.junit.Test;

import java.util.*;

public class CollectionTest {

@Test

public void test1(){

Collection coll = new ArrayList();

//1.add():将元素e添加到coll中

coll.add("AA");

coll.add("BB");

coll.add(123);//自动装箱

coll.add(new Date());

//2.size():获取添加的元素的个数

System.out.println(coll.size());

//3.addAll(Collection coll1):将coll1集合中的元素添加到当前的集合中

Collection coll1 = new ArrayList();

coll1.add(456);

coll1.add("CC");

coll.addAll(coll1);

System.out.println(coll.size());

System.out.println(coll);

//4.clear():清空集合元素

coll.clear();

//5.isEmpty():判断当前集合是否有元素

System.out.println(coll.isEmpty());

}

@Test

//注意:向Collection接口的实现类的对象中添加数据obj时,要求所在类要重写equals()

public void test2(){

Collection coll = new ArrayList();

coll.add(123);

coll.add(456);

coll.add(new String("Tom"));

coll.add(false);

coll.add(new Person("Jerry",21));

//6.contains(Object obj):判断当前集合中是否包含obj

boolean contains = coll.contains("Jerry");

System.out.println(contains);

//7.containsAll(Collection coll1):判断形参coll1中的所有元素是否都存在于当前集合中。

Collection coll1 = Arrays.asList(132,456,789);

System.out.println(coll.containsAll(coll1));

//8.remove(Object obj):从当前集合中移除obj元素。

System.out.println(coll.remove(123));

//9.removeAll(Collection coll1):从当前集合中移除coll1中的所有元素,差集

coll.removeAll(coll1);

System.out.println(coll);

System.out.println(coll1);

//10.retainAll():求交集

coll.retainAll(coll1);

System.out.println(coll);

//11.equals():有序的比较两个集合。全等返回true

//12.hashCode():返回当前对象的哈希值

//13.toArray() 集合 ---> 数组

Object[] arr = coll.toArray();

for (int i = 0; i < arr.length; i++) {

System.out.println(arr[i]);

}

}

@Test

public void test3(){

Collection coll = new ArrayList();

coll.add(123);

coll.add(456);

coll.add(new String("Tom"));

coll.add(false);

coll.add(new Person("Jerry",21));

//14.toArray() 集合 ---> 数组

Object[] arr = coll.toArray();

for (int i = 0; i < arr.length; i++) {

System.out.println(arr[i]);

}

//15.asList():数组 ---> 集合

List list = Arrays.asList(new String[]{"A", "C", "H", "M", "B"});//new 包装类的对象

System.out.println(list);

}

}

2.Iterator迭代器接口。遍历集合元素

●Iterator对 象称为迭代器(设计模式的一种),主要用于遍历Collection 集合中的元素。

●GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式,就是为容器而生。类似于“公交车.上的售票员”、“火车上的乘务员”、“空姐”。

●Collection接口继承了java.lang.lterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。

●Iterator仅用于遍历集合,Iterator本身并不提供承装对象的能力。如果需要创建Iterator对象,则必须有一个被迭代的集合。

●集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。

package com.xudong.java;

import org.junit.Test;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;

public class IteratorTest {

@Test

public void test1(){

Collection coll = new ArrayList();

coll.add(123);

coll.add(456);

coll.add(new String("Tom"));

coll.add(false);

coll.add(new Person("Jerry",21));

//遍历集合种元素

Iterator iterator = coll.iterator();

System.out.println(iterator.next());

//方法一:不推荐

// for (int i = 0; i < coll.size(); i++) {

// System.out.println(iterator.next());

// }

//方法二:

while (iterator.hasNext()){

System.out.println(iterator.next());

}

//remove移除指定元素

Iterator iter = coll.iterator();

while (iter.hasNext()){

Object obj = iter.next();

if ("Tom".equals(obj)){

iter.remove();

}

}

System.out.println(coll);

}

}

Iterator新特性

使用foreach循环遍历集合元素

●Java 5.0提供了foreach 循环迭代访问Collection和数组。

●遍历操作不需获取Collection或数组的长度,无需使用索引访问元素。

●遍历集合的底层调用Iterator完成操作。

●foreach还可以用来遍历数组。

package com.xudong.java;

import org.junit.Test;

import java.util.ArrayList;

import java.util.Collection;

public class forTest {

@Test

public void test(){

Collection coll = new ArrayList();

coll.add(123);

coll.add(456);

coll.add(new String("Tom"));

coll.add(false);

coll.add(new Person("Jerry",21));

//for(集合元素类型 局部变量 : 集合对象)

for (Object obj : coll){

System.out.println(obj);

}

}

@Test

public void test1(){

int[] arr = new int[]{1,2,33,2,5,4,6,7};

//for(数组元素类型 局部变量 : 数组对象)

for (int i : arr){ //将arr取到的值赋给i,数组内容不会改变。

System.out.println(i);

}

}

}

3.List接口

3.1 List接口概述

●鉴于Java中数组用来存储数据的局限性,我们通常使用List替代数组

●List集合类中元素有序、且可重复,集合中的每个元素索都有其对应的顺序索引。

●List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。

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

ArrayList: 作为List接口的主要实现类;线程不安全的,效率高;底层使用Object[] elementData存储

LinkedList: 对于频繁的插入、删除操作,使用此类效率E比ArrayList高; 底层使用双向链表存储

Vector: 作为List接口的古老实现类;线程安全的,效率低;底层使用Object[] elementData存储

3.2 ArrayList 源码分析

jdk 7情况下

ArrayList list = new ArrayList();//底层创建了长度是10的Object[]数组elementData

list.add(123);//eLementData[e] = new Integer(123);

...

list.add(11);//如果此次的添加导致底层eLementData数组容量不够,则扩容。

默认情况下,扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中。

结论:建议开发中使用带参的构造器: ArrayList list = new ArrayList(int capacity)

jdk 8中ArrayList的变化:

ArrayList list = new ArrayList();//底层Object[] elementData初始化为{}.并没有创建长度为10的数组

list.add(123);//第一次调用add()时,底层才创建了长度10的数组,并将数据123添加到eLementData

后续的添加和扩容操作与jdk 7无异。

小结: jdk7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8 中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。

3.3 LinkedList 源码分析

Linkedlist list = new LinkedList(); //内部声明了Node类型的first和last属性,默认值为null

list. add(123);//将123封装到Node中,创建了Node对象。

3.4 List接口方法

●List除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来操作集合元素的方法。

?void add(int index, Object ele):在index位置插入ele元素

?boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来

?Object get(int index):获取指定index位置的元素

?int indexOf(Object obj):返回obj在集合中首次出现的位置

?int lastlndexOf(Object obj): 返回obj在当前集合中未次出现的位置

?Object remove(int index):移除指定index位置的元素,并返回此元素

?Object set(int index, Object ele):设置指定index位置的元素为ele

?List subList(int fromIndex, int tolndex):返回从fromIndex到toIndex位置的子集合

4.Set接口

4.1 Set接口概述

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

●Set集合是无序的,不可重复的。

?无序性:不等于随机性。存储的数据根据哈希值存储

?不可重复性:保证添加的元素按照equals()判断时,不能返回true。

●Set判断两个对象是否相同不是使用==运算符,而是根据equals()方法

4.2 Set实现类之一:HashSet

●HashSet是Set接口的典型实现,大多数时候使用Set集合时都使用这个实现类。

●HashSet按Hash算法来存储集合中的元素,因此具有很好的存取、查找、删除性能。本质上是数组与链表的结合体。

●HashSet具有以下特点:

?不能保证元素的排列顺序

?HashSet不是线程安全的

?集合元素可以是null

●HashSet集合判断两个元素相等的标准:两个对象通过hashCode()方法比较相等,并且两个对象的equals()方法返回值也相等。

●对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则。即:“ 相等的对象必须具有相等的散列码”。

4.3 Set实现类之二:LinkedHashSet

●LinkedHashSet是HashSet的子类

●LinkedHashSet根据元素的hashCode值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的。遍历其内部数据时,可以按照添加的顺序遍历。

●LinkedHashSet插入性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。

●LinkedHashSet不允许集合元素重复。

4.4 Set实现类之三:TreeSet

●TreeSet是SortedSet接口的实现类,TreeSet 可以确保集合元素处于排序状态。

●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采用自然排序。

●向TreeSet中添加的数据,要求是相同类的对象。

添加元素的过程,以HashSet为例:

我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,

此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断数组此位置上是否已经有元素:

如果此位置上没有其他元素,则元素a添加成功。---> 情况1

如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:

如果hash值不相同,则元素a添加成功。---> 情况2

如果hash值相同,进而需要调用元素a所在类的equlas()方法:

equals()返回true,元素a添加失败

equaLs()返回false,则元素a添加成功。--->情况3

对于添加成功的情况2和情况3而言:

元素a与已经存在指定索引位置上数据以链表的方式存储。

jdk 7 :元素a放到数組中,指向原来的元素。

jdk 8 :原来的元素在数組中,指向元素a

Map接口

1.Map的实现类

/----Map:双列数据,存储key-value对的数据--- 类似于高中的函数: y = f(x)

/----HashMap:作为Map的主要实现类;线程不安全的,效率高;存储null 的key和value

/----LinkedHashMap:保证在遍历map元素时,可 以按照添加的顺序实现遍历。

原因:在原有的HashMap底层结构基础上,添加了一对指针,

指向前一个和后一个元素。对于频繁的遍历操作,此类执行效率高FHashMap。

/---- TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序底层使用红黑树

/----Hashtable:作为古老的实现类;线程安全的,效率低;不能存储null的key value

/----Properties: 常用来处理配置文件。key 和value都是String类型

HashMap的底层: 数组+链表 (jdk7及之前)

数组+链表+红黑树 (jdk 8)

Map结构的理解:

Map中的key:无序的、不可重复的,使用Set存储所有的key ---> key所在的类要重写 equals() 和 HashCode() (HashMap为例)

Map中的value:无序的、可重复的,使用Collection存储所有的value。---> value 所在的类要重写 equals()

一个键值对: key-value 构成了一个Entry对象。

Map中的entry:无序的、不可重复的,使用Set存储所有的entry

2.Map接口常用的方法:

●添加、删除、修改操作:

?Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中

?void putAI(Map m):将m中的所有key-value对存放到当前map中

?Object remove(Object key):移除指定key的key-value对,并返回value

?void clear():清空当前map中的所有数据

●元素查询的操作:

?Object get(Object key):获取指定key对应的value

?boolean containsKey(Object key):是否包含指定的key

?boolean containsValue(Object value):是否包含指定的value

?int size():返回map中key-value对的个数

?boolean isEmpty():判断当前map是否为空

?boolean equals(Object obj):判断当前map和参数对象obj是否相等

●元视图操作的方法:

?Set keySet():返回所有key构成的Set集合

?Collection values():返回所有value构成的Collection集合

?Set entrySet():返回所有key-value对构成的Set集合

3.HashMap的底层实现原理

?JDK7.0

HashMap map = new HashMap():

在实例化以后,底层创建了长度是16的一维数组Entry[] table.

...可能已经执行过多i次put...

map.put (key1, value1):

首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到在Entry 数组中的存放位置。如果此位置上的数据为空,此时的key1-value1 添加成功。---- 情况1

●如果此位置上的数据不为空,( 意味着此位置上存在-一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据的哈希值:

●如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1 添加成功。---- 情况2

●如果key1的哈希值和已经存在的某一个数据(key2-value2) 的哈希值相同,继续比较:调用key1所在类的equals(key2)

●如果equals()返回false:此时key1-value1添加成功。---- 情况3

●如果equaLs()返@true:使用value1替换value2。

补充:关于情况2和情况3:此时key1-value1 和原来的数据以链表的方式存储。

在不断添加的过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时,扩容。

默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来。

?jdk8相较于jdk7在底层实现方面的不同:

1. new HashMap():底层没有创建一一个长度为16的数组

2. jdk 8底层的数组是: Node[], 而非Entry[]

3.首次调用put()方法时,底层创建长度为16的数组

4. jdk7 底层结构只有:数组+链表。jdk8 中底层结构:数组+链表+红黑树。

当数组的某一个索引位置上的元素以链表形式存在的数据个数> 8且当前数组的长度> 64时,此时此索引位置上的所有数据改为使用红黑树存储。

4.HashMap源码中的重要常量

**DEFAULT_INITIAL_CAPACITY **: HashMap的默认容量,16

**MAXIMUM_CAPACITY **: HashMap的最大支持容量, 2^30

DEFAULT_LOAD_FACTOR: HashMap的默认加载因子0.75

TREEIFY_THRESHOLD: Bucket中链表长度大于该默认值8,转化为红黑树

UNTREEIFY_THRESHOLD: Bucket中红黑树存储的Node小于该默认值,转化为链表MIN_TREEIFY_CAPACITY:桶中的Node被树化时最小的hash表容量64。(当桶中Node的数量大到需要变红黑树时,若hash表容量小于MIN_TREEIFY_CAPACITY时,此时应执行) resize扩容操作这个MIN_TREEIFY_CAPACITY的值至少是TREEIFY_THRESHOLD的4倍。)

table:存储元素的数组,总是2的n次幂

entrySet:存储具体元素的集

size: HashMap中存 储的键值对的数量

modCount: HashMap扩容和结构改变的次数。

threshold:扩容的临界值12,=容量填充因子 (160.75)= 12

loadFactor:填充因子

5.LinkedHashMap底层原理

6.Properties

●Properties类是Hashtable的子类,该对象用于处理属性文件

●由于属性文件里的key、value 都是字符串类型,所以Properties里的key和value都是字符串类型

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

五、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处元素进行交换

1.Collections常用方法

查找、替换

●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中

List dest = Array.asList(new Object[src.size()]);

Sysout.out.println(dest.size);//src.size()

Collections.copy(dest,src);

Sysout.out.println(dest);

●boolean replaceAll(List list, Object oldVal, Object newVal):使用新值替换List对象的所有旧值

同步控制

●Collections类中提供了多个synchronizedXxx()方法,该方法可使将指定集合包装成线程同步的集合,从而可以解决多线程并发访问集合时的线程安全问题

java集合代码_Java-集合(示例代码)相关推荐

  1. java 9999 符号_java 9999(示例代码)

    1. map 1.1. map中的方法 1.2. Map.Entry 对于集合来讲,就是把kye-value的数据保存在了Map.Entry的实例之后,再在Map集合中插入了一个Map.Entry的实 ...

  2. java异常代码_Java异常(示例代码)

    Java异常处理 程序发生异常的原因有很多,通常包含以下几类: 用户输入非法数据 要打开的文件不存在 网络通信连接中断,或者JVM内存溢出 异常有的是因为用户错误引起的,有的是程序错误引起的,还有一些 ...

  3. arcgis sample代码之SOE示例代码PageLayout REST Server Object Extension 的源码分析

    0.前言 研究 arcgis object的代码是十分重要的,对于学习arcObject太重要了,因为没有这些代码,学习混乱的arcObject将会更佳的困难. 我的arcgis server 是10 ...

  4. java实时汇率的接口_eoLinker-API_Shop_汇率查询_API接口_Java调用示例代码

    eoLinker-API Shop 汇率查询 Java调用示例代码 汇率查询 提供汇率转换.单个货币对应的热门货币汇率行情,包括人民币.美元.欧元.英镑等100多种货币的实时汇率查询. 该产品拥有以下 ...

  5. java 二十四节气,eoLinker-API_Shop_二十四节气查询_API接口_Java调用示例代码

    eoLinker-API Shop 二十四节气查询 Java调用示例代码 二十四节气查询 二十四节气的时间.由来.习俗以及养生 该产品拥有以下APIs: 1.查询二十四节气 2.查询节气详情 注意,该 ...

  6. java iterator 删除_Java集合使用 Iterator 删除元素

    这篇文章主要介绍了Java集合使用 Iterator 删除元素,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 针对常见的数据集合,比如 ArrayL ...

  7. java集合继承_java集合继承关系

    数组虽然也可以存储对象,但长度是固定的:集合长度是可变的,数组中可以存储基本数据类型,集合只能存储对象. 集合类的特点:集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象. 上述类图中, ...

  8. java多线程代码_java多线程实例代码详解

    原文:http://blog.csdn.net/paranoidyang/article/details/70184523 作者:Paranoidyang 线程与进程的区别 (1)程序是一段静态的代码 ...

  9. java书号属性,基于Java的ISBN书号查询示例代码-六派数据

    示例代码 本代码示例是基于Java的六派数据接口进行数据请求API服务请求的代码示例,使用前你需要: 以下是完整代码示例: /** * 主函数 * @param args */ public stat ...

  10. java 集合 接口_Java集合之Collection接口

    1 - Java集合介绍 /* 1. 一方面, 面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象 的操作,就要对对象进行存储. 2. 另一方面,使用Array存储对象方面具有一些弊 端,而 ...

最新文章

  1. java设计模式---职责链模式
  2. Oracle安装步骤及PL/SQL Developer连接数据库
  3. 今日arXiv精选 | 14篇EMNLP 2021最新论文
  4. VueJS ReactJS 如何?听听别人怎么说。
  5. Codeforces Round #348 (VK Cup 2016 Round 2, Div. 2 Edition) D. Little Artem and Dance 模拟
  6. openSUSE 11 上的配置可以Xmanager远程桌面
  7. Android之可伸缩的皮筋效果(贝塞尔曲线)的介绍
  8. ORACLE中使用递归查询
  9. 前端:JS/22/函数(函数的概念,函数的定义格式,函数定义格式的说明,函数的调用,函数的参数),全局变量和局部变量,拷贝传值和引用传址,匿名函数,二维数组,对象,自定义对象的创建
  10. java jdbc close原理_Java开发笔记(一百四十六)JDBC的应用原理
  11. 47. 不用加减乘除做加法(C++版本)
  12. 编程基础(三)——体系结构
  13. linux安装pip3_Liunx下安装Python3.5.0版本,本地有python2.7.5,python2和3共存
  14. 模型预测控制的缺点_基于模型预测控制的车辆纵向跟车模型分析
  15. oppo9s刷机教程_OPPOR9S刷机包
  16. oracle中isnumber函数,Oracle 函数isnumber问题
  17. 国际奥林匹克运动会是怎么来的?
  18. python 根据银行卡号获取对应的银行
  19. python写微信小程序商城,oejia_weshop
  20. python爬音乐评论生成词云图_Python ---网易云音乐评论自动云图生成器

热门文章

  1. C# DataTable 转换成ListT
  2. 腾讯UED 漂亮的提示信息
  3. 非营利组织Eatbch展示了每一个小的微交易是如何起作用的
  4. wpf控件设计时支持(2)
  5. 给初学者的一点建议,新手学习java需要学习哪些基础?
  6. 利用Attribute简化Unity框架IOC注入
  7. Javascript 上课笔记
  8. Java 8 类型转换及改进
  9. bind日志配置详解
  10. 活动目录迁移之03奔向08 --10月18日2008系列讲座预告篇