一、
1.概述:对多个对象进行存储,只在内存层面的存储,不涉及到持久化的存储(.txt,.jpg,.avi,数据库)
2数组 特点:一旦初始化后,长度就确定了
数组一旦定义好,元素数据类型也确定了,就只能操作指定数据类型的数据 eg: String[ ] arr ,int [ ] arr1,Object[ ] arr2
缺点: 初始化后,长度不可修改
数组中提供的方法有限,对于添加、删除、插入数据等操作,非常不便,效率不高。
获取数组中实际元素个数的需求,数组没有现成的属性或方法可用
数组存储数据的特点:有序、可重复、对于无序、不可重复的需求,不能满足
二、集合框架
Collection接口 :单列集合,用来存储一个一个的对象
List接口:存放有序的,可重复的数据 动态数组,长度可修改
实现类:ArrayList、LinkedList、Vector
Set接口:存储无序的、不可重复的数据 类似高中讲的集合
实现类:HashSet、LinkedHashSet、TreeSet
Map接口 :双列集合,用来存储一对一对的数据(key-value) 类似高中函数y=f(x)
实现类:HashMap、LinkedHashMap、TreeMap、Hashtable、 Properties
三、Collection接口中的方法
public class Main {
public static void main(String[] args) {
CollectionTest test = new CollectionTest();
test.test1();
}
}
public class CollectionTest {
public void test1() {
1 //add(Object e) 把元素e添加到coll中
Collection coll = new ArrayList();//使用接口类型来引用具体实现类对象 多态
coll.add("AA");
coll.add("BB");
coll.add(123);//自动装箱 自动包装成Integer对象
coll.add(new Date());//添加一个Date对象
2 //size()获取元素个数
System.out.println(coll.size());
3 //addAll(Collection coll1) 将coll1集合中的元素添加到当前集合中去
Collection coll1 = new ArrayList();
coll1.add(456);
coll1.add("CC");
coll.addAll(coll1);
System.out.println(coll.size());
4 //clear():清空集合元素
coll.clear();//与null不同,元素不在了,但集合对象还在
5 //isEmpty()判断当前集合是否为空
System.out.println(coll.isEmpty());
6 //Contains(Object obj) 判断当前集合中是否包含obj
//在判断时,会调用obj对象所在类的equals()
结论 /*
向Collection接口的实现类的对象中添加数据时,要求obj所在类重写equals()方法
原Object中 equal判断地址是否相等 重写后判断内容
*/
7 //containsAll(Collection coll) 判断形参coll中的所有元素是否都存在于当前集合中
//remove(Oject obj) 从当前集合中移除obj元素
//removeAll (Collection coll) 差集,从当前集合中移除coll中所有的元素
//retainAll(Collection coll) 交集 获取当前集合和coll集合的交集,并返回给当前集合
//equals(Object obj)想要返回true,需要当前集合和形参集合的元素都相同
//hashCode() 返回当前对象的哈希值
//集合--->数组 toArray()
//数组--->集合 调用Array类的静态方法asList()
List<String> list = Arrays.asList(new String[] {"AA","BB","CC"});
List arr = Array.asList(new int[]{123,456}); 这样写不正确,会将整个当作一个元素
List arr2= Arrays.asList(new Integer[]{123,456});
}
}
,
四. 集合元素的遍历操作,
1.使用迭代器Iterator接口 内部的方法:hasNext()和next()
集合地像每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前
remove()方法
Iterator iterator = coll1.iterator();
while(iterator.hasNext()){//判断是否有下一个元素
System.out.println(iterator.next());//输出元素
}
错误一 跳着输出
Iterator iterator = coll1.iterator();
while(iterator.Next()!=null){
System.out.println(iterator.next());
}
错误二 重复输出第一个元素集合 对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都
在集合的第一个元素之前
while(coll.iterator.hasNext()){//判断当前是否有元素
System.out.println(iterator.next());//输出元素
}
删除remove
Iterator iterator = coll1.iterator();
while(iterator.hasNext()){
Object obj = iterator.next();
if("Tom".equals(obj)){
iterator.remove();
}
System.out.println(iterator.next());
}
查询是否删除
Iterator iterator = coll1.iterator(); //需重新创建指向开头元素上面 因为前面的光标已经到末尾了
while(iterator.hasNext()){
System.out.println(iterator.next());
}
2.foreach循环,用于遍历集合、数组
//for(集合元素的类型 局部变量 : 集合对象)
内部仍然调用了迭代器
for(Object obj:coll){
System.out.println(obj);
}
五 List接口 动态数组替代数组
1.面试题:ArrayList、LinkedList、Vector异同
同:三个类都是实现了List接口,存储数据的特点相同:都存储有序的、可重复的数据
不同:
ArrayList :作为List接口的主要实现类,线程不安全,效率高,底层使用Object[] elementData存储(数组)
LinkedList :对于频繁的插入、删除操作,使用此类效率比ArrayList高,底层使用双向链表存储
Vector:List接口的古早实现类,线程安全,效率低,底层使用Object []elementData存储
2.ArrayList源码分析
2.1jdk7
ArrayList List = new ArrayList();//底层创建了长度为10的Object[]数组elemData
List.add(123);//就是elementData[0] = new Integer(123);
...
List.add(11);//如果此次添加导致底层elementData数组容量不够,默认扩到原来容量的 1.5倍,同时将原有数组中的数据复制到新的数组中去
开发建议使用带参的构造器:ArrayList List = new ArrayList(int capacity)
2.2jdk8
ArrayList List = new ArrayList();//底层Object[] elementData 初始化为{},没有创建长度为10的数组
List.add(123);//第一次调用add()时,底层才创建了长度为10的数组,并将数据123添加 elementData[0]中
...
后续的添加和扩容操作与7无异
2.3小结 jdk7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8中的arrayList的对象创建类似于单例的懒汉式,延迟了数组的创建,节省了内存.
3.LinkedList源码分析
LinkedList list = new LinkedList();//内部声明了Node类型的first和last属性,默认值为null
list.add(123);//将123封装到Node中,创建了Node对象
Node的定义体现了LinkedList的双向链表的说法
4.Vector 源码分析
jdk7和jdk8中通过Vector()的构造器创建对象时,底层都创建了长度为10的数组.
在扩容方面,默认扩容为原来的数组长度的2倍
5.List接口中的常用方法
list.add(Object obj);
list.add(1,"B"); // void add(int index,Object ele) 在index位置上插入ele元素
list.addAll(1,list);// boolean addAll(int index,Collection eles) 从indecx位置开始将list中的所有元素添加进来
list.get(0); // Object get(int index) 获取指定index位置的元素
int index = list.indexOf(456);// int indexOf(Object obj);// 返回obj在集合中首次出现的位置 如果不 存在返回 -1
int lastIndexOf(Object obj)//返回obj在当前集合中末次出现的位置
Object remove(int index) //移除指定index位置的元素,并返回此元素
Object set(int index ,Object ele) // 设定指定index位置的元素为ele
List subList(int fromIndex,int toIndex) //返回从fromIndex到toIndex位置的子集合 左闭右开
总结:常用方法
增add(Object obj)
删remove(int index) / remove(Object obj) 注意区分
...
list.add(1);
list.add(2);
list.(3)
...
list.remove(2);//索引
list.remove(new Integer(2));// 删除元素2
改set(int index ,Object ele)
查get(int index)
插 add(int index,Object ele)
长度size()
遍历 (1)Iterator迭代器方式 (2)增强for循环 (3)普通循环
六 Set接口的框架
1. Set接口中没有额外定义新的方法,使用的都是Collection中声明的方法
要求:向Set中添加的数据,其所在类一定要重写hashCode()和equals()
重写的hashCode()和equals()尽可能保持一致性:相同的对象必须具有相等的散列码
重写小技巧:对象中用作equals()方法比较的Field,都应该用来计算hashCode
HashSet:作为Set接口的主要实现类,线程不安全的,可以存储null值
LinkedHashSet:作为HashSet的子类,遍历其内部数据时,可以按照添加的顺序遍 历。对于频繁的遍历操作,LinkedHashSet效率高于HashSet。
TreeSet:可以按照添加对象的指定属性,进行排序。底层使用红黑树存储.
2. Set:无序、不可重复如何理解
以HashSet为例说明:
(1)无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据 数据的哈希值决定的
(2)不可重复性:保证添加的元素按照equals()判断时,不能返回true,即相同的元素只能添加 一个
3.添加元素的过程:以HashSet为例
4.LinkedHashSet的使用
LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据。对于频繁的遍历操作,LinkedHashSet效率高于HashSet。
5.TreeSet
向TreeSet中添加的数据,要求是相同类的对象
两种排序方式:自然排序(实现comparable接口) 和 定制排序(Comparator)
自然排序中,比较两个对象相同的标准为:compareTo( obj )返回0,不再是equals().
定制排序中,比较两个对象相同的标准为:compare( Object o1,Object 02)返回0,不再是 equals()
Set的两个面试题:
(1)
(2)
(1)sout 输出两个 1001 AA ,1002 BB
(2) 1001 CC , 1002 BB //remove p1 ,先计算1001 CC的哈希值,与1001 AA所对应哈希值 不同,则无效删除
(3)1001 CC ,1002 BB ,1001 CC //添加的1001 CC 先计算其哈希值 发现没有相同的,直接 添加
(4)1001 CC ,1002 BB ,1001 CC ,1001 AA //计算1001 AA哈希值与 第一个添加的元素哈 希值相同,再用equals()方法判断出内容不 同,原先的这个地方放着1001 CC,故添加
七,
1.Map接口
面试题:
(1)HashMap的底层实现原理 ( 以jdk7为例 )
当超出临界值且要存放位置非空时,扩容
jdk8
(2)HashMap 和 Hashtable的异同
(3)CurrentHashMap 与 Hashtable的异同?
2.Map的结构理解
3.LinkedHashMap的底层实现原理(了解)
4.Map中常用方法
注:
(1)put()方法
Map map = new HashMap ();
map.put("AA",123);//添加
map.put("AA",985);//修改
System.out.println(map);//输出 AA 985
(2)元视图操作 即遍历
5.TressMap ...
6.Properties...
7.Collections工具类...
8.小练习...