第四小节之Java 集合类
Java的集合类就像一个容器,专门用来存储Java类的对象。这些类可以存储任意类型的对象,并且长度可变,统称为集合,这些类位于java.util包中,数组也可以保存多个对象,但在某些情况下无法确定到底保存多少个对象,因此数组蒋步仔适用,因为数组的长度不可变。
Colletion:单列集合类的根接口,用于存储一些列符合某种规则的元素,它有两个重要的子接口,分别是List和Set。其中List的特点是元素是有序、元素可重复。Set的特点是元素无序并且不可重复。LIst接口的主要实现类有ArraysList和LinkedList,Set接口的主要实现类有HashSet和TreeSet。
Map:双列集合类的根接口,用于存储具有键(key)、值(value)映射关系的元素,每个元素都包含一对键值,在使用Map集合时可以通过指定的Key找到相应的Value。Map接口的主要实现类有HashMap和TreeMap。
1.1Collection接口:是所用单列集合的父接口
collection接口的方法:
boolean add(Object o)向集合中添加一个元素
boolean addAll(Collection c)将指定Collection中的所有元素添加到该集合中
void clear()删除该集合中的所有元素
boolean remove(Object o)删除该集合中指定的元素
boolean removeAll(Collection c)删除指定集合中的所有元素
boolean isEmpty()判断该集合是否为空
boolean contains(Object o)判断该集合中是否包含某个元素
boolean containsAll(Collection c)判断该集合中是否包含指定集合中的所有元素
Iterator iterator()返回在该集合的元素上进行迭代的迭代器(Iterator),用于遍历该集合所有元素
int size()获取该集合元素个数
1.2List接口:List接口继承自Collection接口,List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素。另外List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。
LIst集合常用的方法:
void add(int index,Object element)将元素element插入在List集合的index处
boolean addAll(int index,Collection c)将集合c所包含的所有元素插入到List集合的index处
Object get(int index)返回集合索引index处的元素
Object remove(int index)删除index索引处的元素,并返回内容
Object set(int index,Object element)将索引index处元素替换成element对象,并将替换后的元素返回
int indexOf(Object o)返回对象o在List集合中出现的位置索引
List subList(int fromIndex,int toIndex)返回从索引fromIndex(包括)到toIndex(不包括)处所有元素集合组成的子集合
1.2.1ArrayList集合:在ArrayList内部封装了一个长度可变的数组对象,当存入的元素超过数组长度时,ArraysList会在内存中分配一个更大的数组来存储这些元素,因此可以将ArrayList集合看作一个长度可变的数组。
ArrayList集合的底层是使用一个数组来保存元素,在增加和删除指定位置的元素时,会导致创建新的数组。
在向ArrayList集合中存储元素时,必须先指定集合中存储什么类型的元素,会产生安全隐患,这涉及到泛型安全机制的问题。
1.2.2LinkedList集合
ArrayList集合在查询元素时速度很快,但是在增删元素时效率较低,LInkedList集合内部维护了一个双向循环链表,在链表中的每一个元素都使用引用的方式来记住它的前一个元素和后一个元素,从而可以将所有的元素彼此链接起来。
LinkedList常用方法:
void add(int index,E element)在此列表中指定的位置插入指定的元素
void addFirst(Object o)将指定元素插入此列表的开头
void addLast(Object o)将指定的元素插入到此列表的结尾
Object getFirst()返回此列表的第一个元素
Object getLast()返回此列表的最后一个元素
Object removeFirst()移除并返回此列表的第一个元素
Object removeLast()移除并返回此列表的最后一个元素
1.3Iterator接口:遍历集合中的所有元素。用于迭代访问
当遍历集合的整个过程,当遍历元素时,首先通过调用ArrayList集合的Iterator()方法获得迭代器对象,然后使用hasNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。需要注意的是,在通过next()方法获取元素时,必须保证要获取的元素存在,否则,会抛出异常。
Iterator迭代器对象在遍历集合时,内部采用指针的方式来跟踪集合中的元素,在调用Iterator的next()方法之前,迭代器的索引位于第一个元素之前,不指向任何元素,当第一个调用迭代器的next()方法后,迭代器的索引会向后移动一位,指向第一个元素并将该元素返回,当再次调用next()方法时,迭代器的索引会指向第二个元素并将该元素返回,以此类推,直到hasNext()方法返回false,表示到达了集合的末尾,终止对元素的遍历。
在迭代时删除元素会导致迭代器预期的迭代次数发生转变,导致迭代器的结构不正确,会抛出异常,可以使用break语句跳出,也可以使用迭代器本身的删除方法remove(),这样对于迭代器本身是可以预知迭代次数的。
1.4foreach循环:增强的for循环,foreach循环用于遍历数组或集合中的元素
1 for(容器中元素的类型 临时变量:容器变量){ 2 执行语句 3 }
在使用也存在一定的局限性,当循环遍历集合和数组时,只能访问集合中的元素,不能对其中的元素进行修改
1.4.1ListIterator接口,是Iterator的子类
常用方法:
void add(Object o)将指定的元素插入列表(可选操作)
boolean hasPrevious()如果以逆向遍历列表,列表迭代器有多个元素,则返回true,如果为0个元素,则返回false。
Object previous()返回列表中的前一个元素
void remove()从列表中移除有next或previous返回的最后一个元素(可选操作)
1 ArrayList LIst =new ArrayList(); 2 ListIterator it=list.listIterator(list.size());//需要传递一个int类型的参数指定迭代的起始位置 3 while(it.hasPrevious()){ 4 Object obj=it.previous(); 5 }
注意:ListIterator迭代器只能用于List集合。
1.5Enumeration接口
JDK提供了一个vector集合,该集合是List接口的一个实现类,用法与ArrayList完全相同,区别在于vector集合时线程安全的,而ArraysList集合是线程不安全的。在vector类中提供了一个elements()方法用于返回Enumeration对象,通过Enumeration对象就可以遍历该集合中的元素。
1 Vector v=new Vector(); 2 Enumeration en=v.element(); 3 while(en.hasMoreElement){//循环判断是否存在下一个元素 4 Object obj=en.nextElement(); 5 }
1.5.1向量
向量vector是java.util包提供的一个用来实现不同类型共存的变长数组的工具类。
vector类的对象(不能是简单数据类型)不但可以保存顺序的一列数据,而且还封装了许多没有用的方法来操作和处理这些数据,比数组功能强大。
适合用vector类的情况:
1、需要处理的对象数组不定,序列中的元素都是对象,或者可以表示为对象。
2、需要将不同类的对象组合成一个数据系列
3、需要做频繁的对象序列中元素的插入和删除
4、经常需要定位序列中的对象或其他查找操作
5、在不同类之间传递大量的数据
1.6Set接口:Set接口中元素无序,并且都会以某种规则保证存入的元素不重现出现
HashSet是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。TreeSet则是以二叉树的方式来存储元素,它可以实现对集合中的元素进行排序。
1.6.1HashSet集合
所存储的元素是不可重复的,并且元素都是无序的。当向HashSet集合中添加一个对象时,首先会调用该对象的HashCode()方法来确定元素的存储位置,然后再调用对象的equals()方法来确保该位置没有重复元素。
为了保证HashSet集合正常工作,要求在存入对象时,重写该类中的hashCode()和equals()方法
hashCode是jdk根据对象的地址或者字符串或者数字算出来的int类型的值
实现comparable<Object>接口内部只有一个要重写的关键方法
1 int compareTo(Object o) 2 { 3 4 }
1.6.2TreeSet集合
TreeSet是Set接口的另一个实现类,它内部采用自平衡的排序二叉树来存储元素,可以保证TreeSet集合中没有重复的元素,并且可以对元素进行排序
特点:存储的元素会按照大小排序,并能除去重复的元素,左子树比根小,右子树比根大(中序遍历)
定义一个类,实现comparator接口,改写compare()方法,在创建TreeSet集合时指定比较器(类的对象)
1.7Map接口
Map是一个双列集合,它的每个元素都包含一个键对象Key和一个值对象Value,键和值对象之间存在一种对应关系,称为映射。从Map集合中访问元素时,只要指定了Key,就能找到对应的Value。
Map集合常用方法:
void put(Object key,Object value)将指定的值与此映射中的指定键关联(可选操作)
Object get(Object key)返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回NUll
boolean containsKey(Object key)如果此映射包含指定键的映射关系,则返回true
boolean containsValue(Object value)如果此映射将一个或多个键映射到指定值,则返回true
Set keySet()返回此映射中包含的键的Set视图
Collection<V>value()返回此映射中包含的值的Collection视图
Set<Map.Entry<K,V>>entrySet()返回此映射中包含的映射关系的Set视图
如果存储了相同的键,后存储的值则会覆盖原有的值,简而言之:键相同,值覆盖
1 Map map=new HashMap(); 2 Set entrySet=map.entrySet(); 3 Iterator it=entrySet.iterator(); 4 while(it.hasNext){ 5 Map.Entry entry=(Map.Entry)(it.next); 6 Object key=entry.getKey(); 7 Object value=entry.getValue(); 8 }
首先调用Map对象的entrySet()方法获得存储在Map中所有映射的Set集合,这个集合中存放了Map.Entry类型的元素(Entry是Map接口内部类),每个Map.Entry对象代表Map中的一个键值对,然后迭代Set集合,获得每一个映射对象,并分别调用映射对象的getkey()和getValue()方法获取键和值。
还提供了一个value()方法,通过该方法可以直接获取Map中存储所有值的Collection集合。
LinkedHashMap类,它是元素迭代的顺序与存入的顺序一致,和LinkedList一样也使用双向链表来维护内部元素的关系。
1.7.1TreeMap:不允许出现重复的键,在TreeMap中是通过二叉树的原理来保证键的唯一性
1.8Properties集合:Map集合中有一个实现类Hashtable是线程安全,取元素很慢,它有一个子类在实际应用中很重要,Properties主要用来存储字符串类型的键和值。
两种方法:setProperty()和getProperty()
可以调用Properties的propertyNames()方法得到一个包含所有键的Enumeration对象,然后在遍历所有的键时,通过调用getProperty()方法获得键所对应的值。
2JDK5.0新特新——泛型
集合可以存储任何类型的对象,但是当把一个对象存入集合后,集合会“忘记这个对象的类型,将该对象从集合中取出来的时候,这个对象的编译类型就变成了Object类型。换句话说,在程序中无法确定一个集合中的元素到底是什么类型。那么在取出元素时,如果进行强制类型转换就很容易出错。
3Collections工具类:针对集合的操作
常用方法:
static<T>boolean addAll(Collection<?super T>c,T...elements)将所有指定元素添加到指定的collection中
static void reverse(List list)反转指定List集合中元素的顺序
static void shuffle(List list)对List集合中的元素进行随机排序(模拟扑克牌的“洗牌”)
static void sort(List list)根据元素的自然顺序对List集合中的元素进行排序
static void swap(List list,int i,int,j)将指定List集合中i处元素和j处元素进行交换
static int binarySearch(List list,Object key)使用二分法搜索指定对象在List集合中的索引,查找的List集合中的元素必须是有序的
static Object max(Collection col)根据元素的自然顺序,返回给定集合中最大的元素
static Object min(Collection col)根据元素的自然顺序,返回给定集合中的最小元素
static boolean replaceAll(List list,Object oldVal,Object newVal)用一个新的newVal替代List集合中所有的旧值oldVal
4Arrays工具类:操作数组
常用方法:Arrays的sort()方法排序
使用Arrays的binarySearch(Object[] a,Objet key)方法查找元素,只能针对排序后的数组进行元素的查找,返回下标
使用Arrays的copyOfRange(int[] original,int from,int to)方法拷贝元素,from表示被复制元素的初始索引(包括),to表示被赋值元素放入最后索引(不包括)'
使用Arrays的fill(Object[] a,Object val)方法填充元素
使用Arrays的toString(int[] arr)方法把数组转换为字符串,把数组以字符串的形式输出
List<T>list=Arrays.asList();返回一个固定大小的列表,受指定数组的支持,其中可以是单个数据类型int、string 或者可以是一个数组名,但这个数组名必须为一种引用类型。该方法返回的ArraysList类是Arrays工具类里面内嵌的一个私有静态类,并不是java.util.ArrayList中的ArrayList类