在学习集合之前,如果我们需要存储多个元素信息,通常我们会使用数字,但数组也存在诸多缺点:
- 数组长度固定不变,不能很好的适应元素数量动态变化的情况。
- 可以通过数组名.Length获取数组的长度,却无法直接获取数组中真实存储的元素数量。
- 数组采用在内存中分配连续空间的存储方式,根据下标可以快速获取对应的元素信息,但根据元素信息查找时效率低下,需要多次比较。在进行频繁插入、删除操作时同样效率低下。
了解了数组的缺点,那么接下来我们学习集合。
Java集合框架包含的内容
集合框架包含三大内容:
1、接口:表示集合的抽象数据类型。图中以虚线框表示。
2、实现:集合框架中接口的具体实现。以实线表示,加粗实线为最常用实现。
3、算法:在一个实现了某个集合框架中的接口对象身上完成某种有用的计算方法,如查找、排序等。Java提供了进行集合操作的工具类Collections,它提供了对集合进行排序等多种算法实现。
从图中我们可以得知,java集合框架中有两大类接口:Collection和Map。其中Collection接口又有两个子接口:List和Set。所以通常说Java集合框架有三大类接口:List、Set、Map。
共同点:
1、都是集合接口。
2、都可以用来存储很多对象。
不同点:
1、Collection存储一组不唯一、无序的对象。
2、Set接口继承Collection接口,存储一组唯一、无序的对象。
3、List接口继承Collection接口,存储一组不唯一、有序的对象。
4、Map存储一组成对的键-值对象,提供key到value的映射。Map中的key不要求有序,不允许重复。value不要求有序,但允许重复。
Iterator是负责定义访问和遍历元素的接口
一:List接口
List接口的常用类有ArrayList和LinkedList。
ArrayList采用的是在内存中分配连续空间的存储方式。
LinkedList采用连表存储方式。
1、ArrayList集合类
//创建ArrayList集合
List arrayList = new ArrayList();
//添加元素
arrayList.add(Object o);
//循环遍历集合
for(int i = 0; i<arrayList.size(); i++){
//因为集合都是Object类型,所以在输出时需要进行强制类型转换
Class c = (Class)arrayList.get(i);
//通过对象获得属性
System.out.println(c.getName);
}
List接口中的常用方法:
- add(Object o); 在末尾添加内容,也可根据下标添加内容,例如:add(1,”“);
- size(); 或许集合中元素的个数
- get(int index); 返回指定索引处的元素,因为返回的值是Object类型,所以需要强制类型转换。
- contains(); 判断列表中是否存在指定元素
- remove(Object o); 根据对象从列表中删除元素
- remove(int index); 根据索引从列表中删除元素
2、LinkedList集合类
在对元素的操作中基本与ArrayList相同,但LinkedList集合有一些特殊的方法:
- addFirst(Object o); //在列表的首部添加元素
- addLast(Object o); //在列表的尾部添加元素
- getFirst(); //返回列表中的第一个元素
- getLast(); //返回列表中的最后一个元素
- removeFirst(); //删除并返回列表中的第一个元素
- removeLast(); //删除并返回列表中的最后一个元素
二:Map接口
Map接口专门用来处理键-值映射数据的存储。
1、HashMap集合类
//创建HashMap对象
Map map = new HashMap();
//添加键值对元素
map.put(key,value);
//通过key获取value
Strint value = (String)map.get(key);
//判断是否存在key键,存在返回true,不存在返回false
map.containsKey(key);
//显示键集、值集、键值对
map.keySet();
map.values();
map;
3:迭代器Iterator
//测试Map通过Iterator遍历
Set keys = map.KeySet(); //取出所有key的集合
Iterator it = keys.iterator(); //获取Iterator对象
while(it.hasNext()){
String key=(String)it.next(); //取出Key
Class c =(Class)map.get(key); //根据key取出对应的值
//输出key,并且通过对象获取属性
System.out.println(key + "\t" + c.getName());
}
//foreach遍历
Set keys = map.KeySet(); //取出所有Key集合
for(Object key : keys){
Class c = (Class)map.get(key); //根据key取出对应的值
//输出key,并且通过对象获取属性
System.out.println(key + "\t" + c.getName());
}
//测试ArrayList通过Iterator遍历
Iterator it = keys.iterator(); //获取Iterator对象
while(it.hasNext()){
Class c =(Class)it.next; //根据key取出对应的值
//输出key,并且通过对象获取属性
System.out.println(c.getName());
}
两者区别:
Map需要先获取Key的集合,然后通过Key过去Value,ArrayList可以直接遍历输出。
共同点:都需要进行强制类型转换,因为集合属于Object类型。
泛型集合
泛型集合在创建集合对象时即指定了集合中的元素类型,因此从集合中取出元素时不需要进行强制类型转换,并且如果把非指定类型的元素放入集合,会出现编译错误。
//测试对List应用泛型
//创建泛型并指定元素类型
List<Dog> dogs = new ArrayList<Dog>();
//或取指定元素无需强制转换类型
Dog dog3 = dogs.get(2);//或许第三个元素的信息
//foreach循环遍历同样无需强制转换
for(Dog dog:dogs){
System.out.print(dog.getName+"\t"+dog.getStrain);
}
//测试对Map应用泛型
//创建泛型并指定元素类型
Map<String,Dog> dogs = new HashMap<String,Dog>();
Set<String> keys = dogs.KeySet(); //取出所有Key集合
Iterator<String> it = keys.iterator();//获取Iterator对象
while(it.hasNext()){
String key = it.next(); //取出所有Key,无需强制类型转换
Dog dog = dogs.get(key); //根据key取出对应的值,无需强制类型转换
System.out.print(key+"\t"+dog.getStrain);
}
//foreach循环遍历同样无需强制转换
for(String key:keys){
Dog dog = dogs.get(key); //根据key取出对应的值,无需强制类
System.out.print(dog.getName+"\t"+dog.getStrain);
}