集合框架
利用闲暇的时间,针对性的 牢固下java基础
1.1.java集合框架包含的内容
- **接口:**是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象
- **实现(类):**是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。
- **算法:**是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。
问题:Collection与Collections的区别?
1.Collection:
是集合类的上层接口。本身是一个Interface,里面包含了一些集合的基本操作。
Collection接口是List接口和Set接口的父接口
2.Collections
Collections是一个集合框架的帮助类,提供了对集合进行排序,遍历等多种算法实现.
最根本的是Collections是一个类,就像一个工具类,服务于Java的Collection框架。
一.List 接口 List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序(插入顺序)的对象。
二.Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。
Set 接口存储一组唯一,无序的对象。
三.Map
Map 接口存储一组键值对象,提供key(键)到value(值)的映射。
问题:list和Set的区别是是什么呢?
-
- Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
-
- Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
-
- List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。
1.2 List 接口的实现类
一.ArrayList
该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。
该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:
List list=Collections.synchronizedList(newLinkedList(...));
LinkedList 查找效率低。
1.3ArrayList 集合类
public static void main(String[] args) {
//1.创建集合对象
List<String> list=new ArrayList();
//2.添加元素
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//3.在指定的索引位置 添加元素
list.add(1,"A");
list.add(1,"看我在哪里?"); //A上面 更新索引
//4.返回列表中的元素个数
System.out.println("总共有:"+list.size()+"条数据");
//5.返回指定索引位置处的元素,取出的元素是Object类型 使用前需要进行强制转换 (在定义集合的时候,我使用了泛型)
String str=list.get(0);
System.out.println("下标标为0的数据是:"+str);
//6.从列表中删除元素
//list.remove("A"); 或者按下标指引删除
//7 .判断列表中是否存在元素 a
if (list.contains("A")==true){
System.out.println("该数据存在");
}
//8.循环遍历
for (String s:list){
System.out.println(s);
}
}
查看运行结果
1.4LinkedList的特殊方法 (比上面的ArrayList基础上新增加的方法)
2.1 Map 接口
public static void main(String[] args) {
/**
* map 键(key) 不能重复,必须代表唯一 值(value)可以重复
*/
Map <String,String> maps =new HashMap();
//1.以 键值对的方式进行存储
maps.put("dg","岛国");
maps.put("dg","东莞"); //此时下面的值 会覆盖了上面的value=岛国
maps.put("zg","中国");
//2.根据键 返回相关联的值
String dg=maps.get("dg");
System.out.println(dg); //东莞
//3.返回元素个数
System.out.println("总共有:"+maps.size()+"条数据"); //2条
//4.返回键的集合 , 可以看到返回的是 Set集合
Set <String> keys=maps.keySet();
System.out.println(keys); // [dg, zg]
//5.返回值的集合
System.out.println(maps.values()); //[东莞, 中国]
// 循环遍历
for (String str:keys){
System.out.println(maps.get(str));
}
//6.判断是否含有指定的键 映射的 键-值对 如果存在返回true
boolean flag=maps.containsKey("zz");
System.out.println(flag); //false
//删除指定的键
//maps.remove("dg");
}
一.通过Map集合存储 一个对象实例 并且循环遍历
public static void main(String[] args) {
//1.创建dog对象
Dog dog1 = new Dog("小白1","品种1");
Dog dog2 = new Dog("小白2","品种2");
Dog dog3 = new Dog("小白3","品种3");
Dog dog4 = new Dog("小白4","品种4");
//2.创建HashMap <key数据类型通常是字符串,值数据类型>
Map maps = new HashMap();
//3.把dog对象存入 HashMap集合 中
maps.put("dog1",dog1);
maps.put("dog2",dog2);
maps.put("dog3",dog3);
maps.put("dog4",dog4);
//4获取所有的key
System.out.println(maps.keySet());
//上面没有使用泛型,我取到了值,可以使用泛型的
Set<String> keys=maps.keySet();
//5.循环输出map中的所有值
//循环Set集合中的中值
for(Object key: keys){
//通过key得到value
Dog dog=(Dog) maps.get(key);
System.out.println(dog);
}
}
结果
[dog4, dog3, dog2, dog1]
Dog{name=‘小白4’, strain=‘品种4’}
Dog{name=‘小白3’, strain=‘品种3’}
Dog{name=‘小白2’, strain=‘品种2’}
Dog{name=‘小白1’, strain=‘品种1’}
二.通过迭代器来循环遍历
public static void main(String[] args) {
//1.创建dog对象
Dog dog1 = new Dog("小白1","品种1");
Dog dog2 = new Dog("小白2","品种2");
Dog dog3 = new Dog("小白3","品种3");
Dog dog4 = new Dog("小白4","品种4");
//2.创建HashMap <key数据类型通常是字符串,值数据类型>
Map maps = new HashMap();
//3.把dog对象存入 HashMap集合 中
maps.put("dog1",dog1);
maps.put("dog2",dog2);
maps.put("dog3",dog3);
maps.put("dog4",dog4);
//通过key去删除值
//maps.remove("dog1");
//4获取所有的key
Set<String> keys=maps.keySet();
//迭代器
Iterator it = keys.iterator();
//it.hasNext()//返回的是boolean 如果有值,则返回true
System.out.println(it.hasNext());
while (it.hasNext()){//如果为 true才会进循环
System.out.println(it.next());
}
}
结果为:
true
dog4
dog3
dog2
dog1
补充 :集合中为什么要开放迭代器功能
首先使用迭代器适用性强,因为如果用for循环遍历,需要事先知道集合的数据结构,而且当换了一种集合的话代码不可重用要修改,不符合开闭原则。而Iterator是用同一种逻辑来遍历集合。其次使用Iterator可以在不了解集合内部数据结构的情况下直接遍历,这样可以使得集合内部的的数据不暴露。
for循环的遍历
ArrayList list = new ArrayList<>();
for(int i = 0; i < list.size(); i++){
System.out.println(list.get(i));
}
迭代器遍历
Iterator it =list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
总结
Java集合框架为程序员提供了预先包装的数据结构和算法来操纵他们。
集合是一个对象,可容纳其他对象的引用。集合接口声明对每一种类型的集合可以执行的操作。
集合框架的类和接口均在java.util包中。
任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。