S2/JAVA/07-集合框架
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了S2/JAVA/07-集合框架相关的知识,希望对你有一定的参考价值。
集合位于java.util包中。
通常说的集合框架共有3大类接口:List,Set和Map。
他们的共同点:都是集合接口,都可以用来存储很多对象。
它们的区别如下:
Collection接口存储一组不唯一(允许重复)、无序的对象。
Set接口继承Collection接口,存储一组唯一(不允许重复)、无序的对象。
List接口继承Collection接口,存储一组不唯一(允许重复)、有序(以元素插入的次序来放置元素,不会重新排列)的对象。
Map接口存储一组成对的键-值对象,提供key(键)到value(值)的映射。Map中的key唯一,无序。Value同样不唯一,无序。
Iterator接口是负责定义访问和遍历元素的接口。
在集合框架中,List可以理解为数组,元素的内容可以重复并且有序。Set可以理解为数学中的集合,里面的数据不重复并且无序。Map可以理解为数学中的集合,只是每个元素都由key和value两个对象组成。
实现List接口的常用类有ArrayList和LinkedList。他们都可以容纳所有类型的对象,包括null,允许重复,并且都保证元素的存储顺序。
ArrayList对数组进行了封装,实现了长度可变的数组。ArrayList存储数据的方式和数组相同,都是在内存中分配连续的空间。他的优点在于遍历元素和随机访问元素的效率比较高。
LinkedList采用链表存储方式,优点在于插入、删除元素时效率比较高。它提供了额外的addFirst(),addLast(),removeFirst()和removeLast()等方法,可以在LinkedList的首部或尾部进行插入或删除操作。这些方法时的LinkedList可被用于堆栈(stack)或队列(quene)。
List接口的add(Object o)方法的参数类型是Object,即使在调用时实参是Dog类型,单系统认为里面只是Object,所以在通过get(int i)方法获取元素的时必须进行强制类型转换,如Dog dog=(Dog)dogs.get(i),否则会出现编译错误。
List接口中定义的各种常用方法
方法名称 |
说明 |
boolean add(Object o) |
在列表的末尾顺序添加元素,起始索引位置从0开始 |
void add(int index,Object o) |
在指定的索引位置添加元素,原索引位置及其后面的元素依次后移,“注意”:新添加元素的索引位置必须介于0和列表中元素个数之间,0可以元素个数不可以。 |
int size() |
返回列表中的元素个数 |
Object get(int index) |
返回指定订索引位置处的元素。“注意”:取出的元素是Object类型,使用前需要进行强制类型转换 |
boolean contains(Object o) |
判断列表中是否存在指定元素 |
boolean remove(Object o) |
从列表中删除元素 |
Object remove(int index) |
从列表中删除指定位置元素,起始索引位置从0开始 |
Vector和Array的异同。
在ArrayList类出现之前,JDK中存在一个和他同样分配连续存储空间、实现了长度可变数组的集合类Vector。两者实现原理相同,功能相同,在很多情况下可以互用。Vector的用法可查询API文档。
Vector和ArrayList的主要区别如下。
Vetctor是线程安全的,ArrayList中速度、轻安全,是线程非安全的,所以当运行到多线程环境中时,需要程序员自己管理线程的同步问题。
当长度需要增长时,Vector默认增长为原来的一倍,而ArrayList只增长50%,有利于节约内存空间。
开发过程中,最好使用新版本的ArrayList。
ArrayList采用了和数组相同的存储方式,在内存中分配连续的空间,在添加和删除非尾部元素时会导致后面所有元素的移动,性能低下。所以在插入、删除操作较频繁时,可以考虑使用LinkedList来提高效率。
LinkedList的一些特殊方法
方法名称 |
说明 |
void addFirst(Object o) |
在列表的首部添加元素 |
void addList(Object o) |
在列表的末尾添加元素 |
Object getFirst() |
返回列表中的第一个元素 |
Object getLast() |
返回列表中的最后一个元素 |
Object removeFirst() |
删除并返回列表中的第一个元素 |
Object removeLast() |
删除并返回列表中的最后一个元素 |
Map中的key不要求有序,不允许重复。Value同样不要求有序,但允许重复。最常用的Map实现类似HashMap,它的存储方式是哈希表。哈希表也称为散列表,是根据关键码值(key value)而直接进行访问的数据结构。也就是说你,他通过把关键码映射到表中一个位置来访问记录,以加快查找速度。存放记录的数组称为散列表。使用这种方式存储数据的优点是查询指定元素效率高。
Map的常用方法
方法名称 |
说明 |
Object put(Object key,Object value) |
以“键-值对”的方式进行存储,“注意”:键必须是唯一的,值可以重复。如果试图添加重复的键,那么最后加入的“键-值对”将替换掉原先的“键-值对” |
Object get(Object key) |
根据键返回相关联的值,若不存在指定的键,则返回null |
Object remove(Object key) |
删除指定的键映射的“键-值对” |
int size() |
返回元素个数回元素个数 |
Set keySet() |
返回键的集合 |
Collection values() |
返回值的集合 |
boolean containsKey(Object key) |
若存在指定的键映射的“键-值对”,则返回true |
boolean isEmpty() |
若不存在键-值映射关系,则返回true |
void clear() |
从此映射中移除所有映射关系 |
Hashtable和HashMap的异同。
HashMap类出现之前,JDK中存在一个和他同样采用哈希表存储方式、同样实现键值映射的集合类Hashtable。两者实现原理相同,功能相同,很多情况向可以互用。
Hashtable和HashMap的主要区别如下。
Hashtable继承自Dictionary类,而HashMap实现了Map接口。
Hahstable是线程安全的,HashMap重速度、轻安全,是线程非安全的,所以当运行到多线程环境中时,需要程序员自己管理线程的同步问题。
Hashtable不允许null值(key和value都不允许),HashMap允许null值(key和value都允许)。
开发过程中最好使用新版本的HashMap。
迭代器Iterator
Collection接口的Iterate()方法返回一个Iterator,然后通过Iterator接口的两个方法即可方便地实现遍历。
boolean hasNext():判断是否存在两一个可访问的元素。
Object next():返回要访问的下一个元素。
JDK1.5加入了增强型for循环,他是for语句的特殊简化版本,我们通常称之为foreach语句。Foreach语句格式:
for(元素类型t 元素不按量x:数组或集合对象){
引用了x的java语句
}
其中,t的类型必须属于“数组或集合对象”的元素类型。使用foreach语句遍历已经存储数据的Map对象,关键代码如下:
/*使用foreach语句输出集合中所有狗狗的信息*/
System.out.println("所有狗狗的昵称和品种分别是:");
Set keys=dogMap.keySet(); //取出所有key集合
for(Object key:keys){
Dog dog=(Dog)dogMap.get(key); //根据key取出对应的值
System.out.println(key+"\t"+dog.getStrain());
}
使用Iterator遍历List
//省略创建狗狗对象
/*创建ArrayList集合对象并把多个狗狗对象放入其中*/
List dogs=new ArrayList();
Dogs.add(ououDog);
Dogs.add(yayaDog);
Dogs.add(meimeiDog);
Dogs.add(2,feifeiDog);
/*通过迭代器依次输出集合中所有狗狗的信息*/
System.out.println("使用Iterator遍历,所有狗狗的昵称和品种分别是:")
Iterator its=dogs.iterator();
While(its.hasNext()){
Dog dog=(Dog)its.next();
System.out.println(dog.getName()+"\t"+dog.getStrain());
}
数组和集合的主要区别包括以下几个方面:
1、数组可以存储基本数据类型和对象,而集合中只能存储对象(可以以包装类形式存储基本数据类型)。
2、数组长度固定,集合长度可以动态改变。
3、定义数组时必须指定数组元素类型,集合默认其中所有元素都是Object。
4、无法直接获取数组实际存储的元素个数,length用来获取数组的长度,但可以通过size()直接获取集合实际存储的元素个数。
5、集合有多种实现方式和不同的使用场合,而不像数组仅采用分配连续空间方式。
6、集合以接口和类的形式存在,具有封装、继承和多态等类的特性,通过简单的方法和属性调用即可实现复杂操作,大大提高了软件的开发效率。
7、JDK中有一个Array类,专门用来操作数组,它提供一系列静态方法实现对数组搜索、排序、比较和填充等操作。JDK中有一个Collections类,专门用来操作集合,它提供一系列静态方法实现对各种集合的搜索、复制、排序和线程安全化等操作。
使用泛型集合在创建集合对象时指定集合中元素的类型,从集合中取出元素时无需进行类型强制转换,并且如果把非指定类型对象放入集合,会出现编译错误。
在以下定义的的ArrayList集合中,泛型为Object,向这个集合中存储的都是基本数据类型,但程序为什么不报错呢?
ArrayList<Object> list=new ArrayList<Object>();
list.add(12);
list.add(25.5);
list.add("男");
list.add(true);
解答:代码中使用了包装类。包装类是指将基本类型封装到一个类中,也就是将基本类型包装成一个类类型。Java程序设计语言为每一种基本类型都提供了一个包装类。而这些包装类就在java.lang包当中,共有8个包装类,Object下有Boolean,Number,Character。Number下又有Byte,Short,Integer,Long,Float,Double。所以共计有Boolean,Character,Byte,Short,Integer,Long,Float,Double这8个包装类。
Boolean类包装布尔类型,Character类包装的是字符,包装所有数字类型的类都继承自Number类,Number类是一个抽象类,包装了Byte,Short,Integer,Long,Float,Double等数字类型,并实现它所定义的方法,这些方法以不同数字格式返回对象的值。
1、包装类常用的构造方法
语法格式如:public Type(type value)
Type表示包装类,type代表基本类型。代码如下:
Integer intValue=new Integer(21);
Long longValue=new Long(21L);
Character charValue=new Character(‘x‘);
Boolean booleanValue=new Boolean(true);
Float floatValue=new Float(21F);
需要注意的是,一旦创建了某个包装类对象,该对象所代表的值就不能改变了。
2、常用的类型转换
(1)包装类→基本类型,语法格式如下。
public type typeValue()
示例代码如下。
Integer integerId=new Integer(25);
int intId=integerId.intValue();
Boolean bl=Boolean.valueOf(true);
boolean bool=bl.booleanValue();
(2)字符串→基本类型,语法格式如下。
public static type parseType(String type)
示例代码如下。
int num=Integer.parseType("36");
bool=Boolean.parseBoolean("false");
以上是关于S2/JAVA/07-集合框架的主要内容,如果未能解决你的问题,请参考以下文章