集合
为什么java中要集合呢,java不是又数组了吗?原因其实很简单,在java中数组的长度是固定的,但是在现实中,很多东西都是在不断的增长的。数组已经满足不了我们的需求了。因此java给我们提供了集合,并对集合实现了一些常用的操作。方便我们的使用。在java集合中被分为两类:Collectionbiaoshi和Map。其中Collection为单列集合;Map为双列集合,以键值对的方式存储。
下面我们来用图表示集合的框架体系:
Collection接口
collection接口是单列集合的根接口,它有两个重要的子接口,分别为List和Set接口。List的特点是元素有序,可重复;Set的特点是元素无序,不可重复。下面是该接口的一些常用方法。
方法声明 | 功能描述 |
---|---|
boolean add(Object o) | 向集合中添加一个元素 |
boolean addAll(Collection c) | 向集合中添加某个集合中的全部元素 |
void clear() | 删除集合中的所有元素 |
boolean remove(Object o) | 移除集合中的一个元素 |
boolean removeAll(Collection c) | 移除集合中某个集合的所有元素 |
boolean isEmpty() | 判断该集合是否为空 |
boolean contains(Object o ) | 判断集合中是否包含某个元素 |
boolean containsAll(Collection c) | 判断集合中是否存在某个集合中的所有元素 |
Iterator iterator() | 获得迭代器 |
int size() | 获得集合大小 |
List
List接口继承了Collection接口。List集合允许有重复的元素,所有的元素都是线性存储的,可以通过索引访问集合中的元素。List集合是有序的存入和取出的顺序是一致的。
ArrayList(线程不安全)
ArrayList是List的一个实现类,它是程序中最常见的一种集合类。在ArrayList内部封装了一个可变长的数组对象,当存储的元素超过数组长度时,ArrayList会在内存中分配更大的数组来存储这些元素。因此看可以把ArrayLIst看成一个可变长数组。
注:对ArrayList对象进行增加或者删除时,都会重新创建一个新的数组,效率较低,不适合做大量的增删操作。但是查找速率很快,原因是可以通过索引访问数据。
LinkedList(线程不安全)
由于ArrayList增删效率低,java有实现了另一个类LinkedList。该集合的内部实现是一个双向循环链表,该集合具有很强的增删操作。
下面是该集合类常用的方法:
方法声明 | 功能描述 |
---|---|
void add(int index, E element) | 在此列表指定位置插入元素 |
void addFirst(Object o) | 在列表头插入元素 |
void addLast(Object o) | 在列表尾插入元素 |
Object getFirst() | 获得列表头元素 |
Object getLast() | 获得列表最后一个元素 |
Object removeFirst() | 移除列表第一个一个元素 |
Object removeLast() | 移除列表最有一个元素 |
Vector(线程安全)
Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:
- Vector 是同步访问的。
- Vector 包含了许多传统的方法,这些方法不属于集合框架。
Vector 主要用在事先不知道数组的大小,或者只是需要一个可以改变大小的数组的情况。HashSet
Set
Set接口也是继承Collection接口,但是与List不同的是Set接口是一个无序,不可重复的集合。Set接口主要有两个实现类:HashSet和TreeSet。HashSet是根据对象的哈希值来确定元素在集合中的位置,因此具有良好的存储和查找性能。TreeSet则是以二叉树的方法来存储元素,它可以实现对集合中元素进行排序。
HashSet(线程不安全)
HashSet类是Set接口的一个实现类。它存储的元素是不能重复的,并且元素是无序的。当向一个HashSet对象添加一个元素,首先会调用添加对象的getHashCode()方法来获得哈希值,从而来确定他的位置。如果只是哈希值相同,在调用对象的equals方法来确定保该位置没有重复元素。存入的对象都要重写Object的getHashCode()和equals()方法。
TreeSet(线程不安全)
TreeSet类是Set接口的一个实现类。它存储的元素是不能重复的,顺序存储,它可以实现对集合中元素的有序排序。它的底层实现是红黑树。如果要用有序的Set集合可以用该集合。
Map
Map接口是一种双列集合,它的每个元素都包含一个键对象Key和一个值对象Value,键和值对象之间存在一种关系,这种关系被称为映射,通过Key对象就可以访问到Value对象。
方法声明 | 功能描述 |
---|---|
void put(Object key , Object value) | 将指定的值与此映射中的指定键关联 |
Object get(Object key) | 返回指定键对应的值 |
boolean containsKey(Object key) | 判断该Map中是否有键为key的映射 |
boolean containsValue(Object value) | 判断该Map中是否有值为value的映射 |
Collection(V) values() | 获得Map中值的Collection视图 |
Set keySet() | 获得Map中key的Set视图 |
Set<Map.Entry<K,V>> entrySet() | 获得Map中映射关系的Set视图 |
Hashtable(线程安全)
Hashtable是Map的一个实现类,他和HashMap十分相似,但是它是线程安全的,但是存取速度很慢,基本上不用,而是用HashMap。
Properties(线程安全)
Properties是Hashtable的一个子类。Properties主要用来存储字符串类型的键值对,主要用来存储应用的配置项。
HashMap(线程不安全)
HashMap集合是Map接口的一个实现类,它用于存储键值对,单必须保证不出现重复的键。如果添加相同键的对象时,后面的添加键对应的值会覆盖原来的值。
如何遍历该集合呢?
一、先遍历Map集合中的键,再根据键获取的Map中的值。
二、先获取集合中的所有映射关系,然后从映射关系中取出键值对。
三、先获取集合中的所有值,然后遍历集合。
public class IteratorMap {
public static void main(String[] args) {
Map map = new HashMap();
map.put("1","1");
map.put("2","2");
map.put("3","3");
//一、先遍历Map集合中的键,再根据键获取的Map中的值。
Set set = map.keySet();
Iterator it = set.iterator();
while(it.hasNext()){
Object key = it.next();
Object value = map.get(key);
System.out.println(key + ":" + value);
}
//二、先获取集合中的所有映射关系,然后从映射关系中取出键值对。
Set entrySet = map.entrySet();
Iterator it1 = entrySet.iterator();
while (it1.hasNext()){
Map.Entry entry = (Map.Entry) it1.next();
Object key1 = entry.getKey();
Object value1 = entry.getValue();
System.out.println(key1 + ":" + value1);
}
//三、先获取集合中的所有值,然后遍历集合。
Collection c = map.values();
Iterator iterator = c.iterator();
while (iterator.hasNext()){
Object value = iterator.next();
System.out.println(value);
}
}
}
TreeMap(线程不安全)
TreeMap是Ma接口的一个实现类。它是以键值实现的红黑树,他是有序的,元素可重复。
Iterator接口
该接口是JDK专门提供给集合进行遍历的一个接口,称为迭代器。它是用指针实现的。下面用代码简单接受一下它对集合的遍历过程。
public static void main(String[] args){
ArrayList<String> arrays = new ArrayList<String>();
arrays.add("jack");
arrays.add("lucy");
arrays.add("tom");
arrays.add("jeny");
Iterator it = arrays.iterator();
while(it.hasnext()){
String str = it.next();
System.out.println(str;
}
}
泛型
集合可以存储任何类型的对象,但是当把一个对象存入集合后,集合会忘记这个对象的类型。当取出来的时候,都会编译成Object类型。我们无法确定该取出的对象,存入的类型是怎么样的。如果这是强制类型转换就很容易出错。为了解决这个问题,java中引入了参数 化类型这个概念,即泛型。如何使用泛型。
ArrayList<type> list = new ArrayList<type>();
此时该集合就只能存储指定类型的对象。取出的时候也是指定的类型。