集合框架
集合框架的概述
引入集合框架
如果存储多个宠物信息用数组来实现,可以定义一个长度为50的Dog类型的数组,存储多个Dog对象的信息,但是采用数组存在以下一些明显缺陷
- 数组长度固定不变,不能很好的适应元素数量动态变化的情况
- 可通过.Length获取数组的长度,却无法直接获取数组中真实存储的狗狗个数
- 数组采用在内存中分配连线空间的存储方式,根据下标可以快速获取对应的狗狗信息,但根据狗狗信息查找时效率低下,需要多次比较
从以上缝隙可以看出,数组处理一些问题时存在明显的缺陷,耳机和完全内部了数组的缺陷,他比数组更灵活更实用,可大大提高软件的开发效率,并且不同的集合可适用于不同场合。
Java集合框架包含的内容
集合框架是为表示和操作集合而规定的一种统一的标准体系结构,集合框架都包含三大块内容对外的接口,接口的实现和对集合运算的算法:
接口:表示集合的抽象数据类型,如Collection,list,set,map,Iterator
实现:集合框架中接口的具体实现,最常用的实现为:ArrayList,LinkedList,HashMap,HashSet;
算法:在一个实现了某个集合框架中的接口对象身上完成某种有用的计算方法,如查找,排序等。Java提供了进行集合操作的工具类Collection,它提供了对集合进行排序等多种算法实现,在使用Collection的时候可以查询JDK帮助文档。
Java集合框架中的两大类接口:Collection和Map.其中,Collection又有两个子接口,List和Set,所以通常说Java集合框架共有三大类接口:List,Set和Map他们的共同点:都是集合接口都可以用来存储很多对象。他们的区别如下:
- Collection,接口存储一组不唯一(允许重复),无序的对象
- Set接口继承Collection,存储一组唯一(不允许重复),无序的对象
- List接口继承Collection接口,存储一组不唯一(允许重复)有序(以元素插入的次序来放置元素,不会重写排列)的对象
- Map接口存储一组成对的键-值对象,提供key到Value的映射,Map中的Key不要求有序,不允许重复。value同样不要求有序。但允许重复
- Iterator接口是负责定义访问和遍历元素的接口
List接口
实现List接口的常用类有ArrayList和LinkedList。他们都可以容纳所有类型的对象,包括null,允许重复,并且都保证元素的存储顺序
ArrayList对数组进行了封装,实现了可变的数组。Arraylist存储数据的方式和数组相同,都是在内存中分配连续的空间。他的优点在于便利元素和随机访问元素的效率比较高。
LinkedList采用链表存储方式。优点在于插入,删除元素是效率比较高,他提高了额外一些方法。这些方法使得LinkedList可被用作堆栈或者队列
ArrayList集合类
public static void main(String[] args) {
Dog a = new Dog("asd","asd");
Dog b = new Dog("a1sd","asd");
Dog c = new Dog("a2sd","asd");
Dog d = new Dog("a3isd","asd");
ArrayList dogs = new ArrayList();
dogs.add(a);
dogs.add(b);
dogs.add(c);
dogs.add(2,d);
System.out.println("删除之前"+dogs.size());
dogs.remove(0);
dogs.remove(d);
for (int i = 0; i < dogs.size(); i++) {
Dog dog = (Dog) dogs.get(i);
System.out.println(dog.getName()+dog.getBrand());
}
if (dogs.contains(c)) {
System.out.println("集合中包含C的信息");
}else {
System.out.println("集合中没有C的信息");
}
}
List接口定义的各种常用方法
方法名称 | 说明 |
---|---|
boolean add(Object o) | 在类表末尾顺序添加元素,其实索引位置从0开始 |
void add(int index,Object o) | 在指定的索引位置添加元素,原索引位置及其后面的元素一次后移 注意:新添加元素的索引位置必须介于0和列表中的元素个数 |
int size() | 返回列表中的元素个数 |
Object get(int index) | 返回指定索引位置处的元素 |
boolean contains(Object o ) | 判断列表中是否存在指定元素 |
boolean remove(Object o ) | 从列表中删除元素 |
Object remove(int index ) | 从列表中删除指定位置元素,起始索引位置从0开始 |
LinkedList集合类
public static void main(String[] args) {
Dog a = new Dog("asd","asd");
Dog b = new Dog("a1sd","asd");
Dog c = new Dog("a2sd","asd");
Dog d = new Dog("a3isd","asd");
LinkedList dogs = new LinkedList();
dogs.add(a);
dogs.add(b);
dogs.addLast(c);
dogs.addFirst(d);
Dog dogFirst=(Dog)dogs.getFirst();
System.out.println(dogFirst.getName()+dogFirst.getBrand());
Dog dogLast=(Dog)dogs.getLast();
System.out.println(dogLast.getName()+dogLast.getBrand());
dogs.removeFirst();
dogs.removeLast();
System.out.println("删除部分狗狗"+dogs.size());
System.out.println("分别是");
for (int i = 0; i < dogs.size(); i++) {
Dog dog = (Dog) dogs.get(i);
System.out.println(dog.getName()+dog.getBrand());
}
}
LinedList的一些特殊方法
方法名称 | 说明 |
---|---|
void addFirst(Object o) | 在列表的首部添加元素 |
void addLast(Object o) | 在列表的末尾添加元素 |
Object getFirst() | 返回列表中的第一个元素 |
Object getList() | 返回列表中的最后一个元素 |
Object removeFirst() | 删除并返回列表中的第一个元素 |
Object removeLast() | 删除并返回列表中的最后一个元素 |
Map接口
HashMap集合类
public static void main(String[] args) {
Map countries = new HashMap();
countries.put("CN","中华人民共和国");
countries.put("RU","俄罗斯");
countries.put("FR","法兰西");
countries.put("US","美利坚");
String country = (String)countries.get("CN");
System.out.println("Cn对应的国家"+country);
System.out.println("MAp中包含FR的Key吗?"+countries.containsKey("FR"));
countries.remove("FR");
System.out.println("MAp中包含FR的Key吗?"+countries.containsKey("FR"));
System.out.println(countries.keySet());
System.out.println(countries.values());
System.out.println(countries);
countries.clear();
if (countries.isEmpty()) {
System.out.println("已清空");
}
}
map接口存储一组承兑的键=值对象,提供key到value的映射.Map中的Key不要求有序,不允许重复。value同样不要求有序,但允许重复,最常用的Map实现类是HashMap,他的存储方式是哈希表,它通过关键码映射到表中一个位置来访问记录,以加速查找速度,存放记录的数组称为散列表。使用这种方式存储数据的有点是查询指定元素效率高;
Map的常用方法
方法名称 | 说明 |
---|---|
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 | 从此映射中一处关系,则返回true |
Object put(Object key,Object value) | 以键-值的方式进行存储 |
迭代器Iterator
所有集合接口何磊都没有提供相应的遍历方法,而是把遍历交给迭代器Iterator完成。Iterator为集合而生,专门实现集合的遍历,他隐藏可各种集合实现类的内部细节,提供了遍历集合的同意编程接口。
Collection接口的Iterator()方法返回一个Iterator,然后通过Iterator接口的两个方法即可方便的实现遍历。
- Boolean hasNext();判断是否存在另一个可访问的元素
- Object next();返回要访问的下一个元素
public static void main(String[] args) {
Dog a = new Dog("asd","asd");
Dog b = new Dog("a1sd","asd");
Dog c = new Dog("a2sd","asd");
Dog d = new Dog("a3isd","asd");
Map dogMap = new HashMap();
dogMap.put(a.getName(),a);
dogMap.put(b.getName(),b);
dogMap.put(c.getName(),c);
dogMap.put(d.getName(),d);
System.out.println("使用Iterator便利");
Set keys = dogMap.keySet();
Iterator it = keys.iterator();
while (it.hasNext()) {
String key = (String)it.next();
Dog dog = (Dog)dogMap.get(key);
System.out.println(key+dog.getBrand());
}
}
泛型集合
前面已经提到,Collection的add(Object obj)方法的参数是O不佳而传统类型,无论把什么对象放入Collection及其子接口或实现类中,认为只是Object类型再通过get(int index)方法取出集合中元素时必须进行强制类型转换,不仅繁琐而且容易出现ClassCastException异常。Map中使用put(Object key,Object value)方法存取对象时,使用Iterator的next()方法来获取元素时也存在同样的问题。所以JDK1.5中已经改写了集合框架中的所有接口和类,增加了泛型的支持。
使用泛型集合在创建集合对象时指定集合元素的类型,从集合中取出元素时无需进行类型强制转换,并且如果把非指定类型对象放入集合,会出现编译报错
泛型集合的应用
list和ArrayList应用泛型
public static void main(String[] args) {
Dog a = new Dog("asd","asd");
Dog b = new Dog("a1sd","asd");
Dog c = new Dog("a2sd","asd");
Dog d = new Dog("a3isd","asd");
List<Dog> dogs = new ArrayList<Dog>();
dogs.add(a);
dogs.add(b);
dogs.add(c);
dogs.add(2,d);
Dog dog3 = dogs.get(2);
System.out.println("第三只狗狗信息如下");
System.out.println(dog3.getName()+dog3.getBrand());
System.out.println("一共有"+dogs.size());
for (Dog dog:dogs) {
System.out.println(dog.getBrand()+dog.getName());
}
}
Map和HashMap应用泛型
public static void main(String[] args) {
Dog a = new Dog("asd","asd");
Dog b = new Dog("a1sd","asd");
Dog c = new Dog("a2sd","asd");
Dog d = new Dog("a3isd","asd");
Map<String,Dog> dogMap = new HashMap<String,Dog>();
dogMap.put(a.getName(),a);
dogMap.put(b.getName(),b);
dogMap.put(c.getName(),c);
dogMap.put(d.getName(),d);
System.out.println("使用Iterator便利");
Set<String> keys = dogMap.keySet();
Iterator<String> it = keys.iterator();
while (it.hasNext()) {
String key = (String)it.next();
Dog dog = (Dog)dogMap.get(key);
System.out.println(key+dog.getBrand());
}
for (String key:keys) {
Dog dog = dogMap.get(key);
System.out.println(key+dog.getBrand());
}
}
使用泛型集合在创建集合对象时指定集合中元素类型,在从集合取出元素时无须进行类型强制转换,避免了ClassCastException异常