java集合
集合、数组都是对多个数据存取的操作,简称java容器
此时的存储,主要指内存层面,不涉及持久化的存储
数组:
java集合
Collection继承树结构(虚线实现类,实现子接口)
Map继承树结构
Collection类
代码演示:
@Test
public void test1() {
Collection coll = new ArrayList();
//add(E e):添加元素
coll.add("AA");
coll.add(123); //自动类型装箱
coll.add(new Date());
//size():获取coll集合中元素个数
System.out.println(coll.size()); //3
//addAll(Collection coll1):将coll1的元素添加到集合中
Collection coll1 = new ArrayList();
coll1.add(456);
coll1.add("BB");
coll.addAll(coll1);
System.out.println(coll.size()); //5
//clear():清空集合元素
coll.clear();
//isEmpty():判断当前集合是否为空
System.out.println(coll.isEmpty()); //true
List类:(存储有序的、可重复的数据)动态数组
面试题:
ArrayList,LinkedList,Vector三者的异同?
相同:
- 三个类都是实现了List接口,存储数据的特点相同
不同:
- ArrayList:作为List接口主要实现类,线程不安全,效率高,底层使用Object[ ] elementData存储
- LinkedList:对于频繁的插入、删除操作,使用此类效率比ArrayList高;底层使用双向链表存储
- Vector:作为List接口的古老实现类;线程安全,效率低;底层使用Object[ ] elementData存储
ArrayList底层源码:
jdk 7情况下类似饿汉模式
jdk 8情况下类似懒汉模式
LinkedList底层源码:
**Vector底层源码:**jdk 8
面试题:
@Test
public void testListRemove() {
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(3);
updateList(list);
System.out.println(list);
}
private void updateList(List list) {
list.remove(2); //2代表索引
list.remove(new Integer(2)); //2代表内容
Set类:(存储无序的、不可重复的数据)
理解Set子接口的特点(Set接口没有额外定义新的方法)
- 无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的
- 不可重复性:底层数组+链表方式,首先按照哈希值取模运算(具体某种算法),计算出在HashSet底层数组中的存放位置(即索引位置)。
如果此位置上没有元素,则添加成功;反之,则比较该元素与其他元素的Hash值,
如果hash值不同,添加成功;反之,进而需要调用equals()方法
返回true,添加失败;反之,成功
可见HashSet底层源码就是HashMap
不是顺序存储
@Test
public void test1() {
Set set = new HashSet();
set.add(456);
set.add(123);
set.add("AA");
set.add("CC");
set.add(new Person(name: "Tom", age: 12));
set.add(129);
Iterator iterator = set.iterator();
while(iterator.hashNext()) {
System.out.println(iterator.next());
}
}
也不是顺序存储,多了指针读出一致
@Test
public void test1() {
Set set = new LinkedHashSet();
set.add(456);
set.add(123);
set.add("AA");
set.add("CC");
set.add(new Person(name: "Tom", age: 12));
set.add(129);
Iterator iterator = set.iterator();
while(iterator.hashNext()) {
System.out.println(iterator.next());
}
}
错误方式:
@Test
public void test2() {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person(name: "Jerry",age: 20));
coll.add(new String("Tom");
coll.add(false);
//错误方式一:
Iterator iterator = coll.iterator();
while((iterator.next()) != null) {
System.out.println(iterator.next());
}
//错误方式二:
//集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个之前
while (coll.iterator().hasNext()) {
System.out.println(coll.iterator().next());
}
//正确方式
Iterator iterator = coll.iterator();
while(iterator.hasNext()) {
Object obj = iterator.next();
if ("Tom".equals(obj)) {
iterator.remove();
}
}
}
练习题:
@Test
public void test3() {
String[] arr = new String[]{"MM,"MM","MM"};
//方式一:普通for赋值
for(int i = 0; i < arr.length; i++) {
arr[i] = "GG"; //会改变原值
}
//方式二:增强for循环
for(String s : arr) {
s = "GG"; //不会改变原值
}
Map类
常用方法:
底层实现原理:
jdk7
2倍扩容
jdk8
赋初值数组
Collections类