文章目录
List接口
- Collection接口:单列集合,用来存储一个一个的对象.
- List接口:存储有序的,可重复的数据.—>"动态"数组
- ArrayList
- LinkedList
- Vector
- Set接口:存储无序的,不可重复的数据.—>高中讲的"集合"
- HashSet
- LinkedHashSet
- TreeSet
- List接口:存储有序的,可重复的数据.—>"动态"数组
概述
面试题
ArrayList,LinkedList,Vector三者的异同?
List接口: JDK1.2版本出现,存储有序的,可重复的数据.(动态数组)
-
同: 三个类都实现了List接口,存储数据的特点相同:存储有序的,可重复的数据
-
不同:
- ArrayList: jdk1.2版本,作为List接口的主要实现类,线程不安全的,效率高.查询效率高,底层用Object[ ] elementData==数组存储.
- LinkedList: jdk1.2版本,对于频繁的插入和删除操作,使用此类效率比ArrayList高,底层低用双向链表存储,每个元素视为一个Node.
- Vector: jdk1.0版本,作为List接口的古老实现类,线程安全的,效率低.底层会用Object[ ] elementData数组存储.
-
面试题:区分remove
ArrayList源码分析: JDK7 情况下
-
底层用Object[ ] elementData数组存储.用构造器new时,直接实例化.创建一个容量为10的数组
-
初始化数组容量为10
-
默认情况下,容量扩容为原来的1.5倍,同时需要将原有数组中的数据复制到新的数组中
-
结论:
建议开发中使用带参的构造器:ArrayList list=new ArrayList(int capacity)
ArrayList源码分析: JDK8 情况下
-
变化:ArrayList list=new ArrayList();//底层Object[ ] elementData初始化为{},并没有创建长度为10的数组.
-
list.add(123);//第一次调用add()时,底层才创建了长度为10的数组,并将数据123添加到elementData[0],后续的添加和扩容操作与jdk7无异.
-
小结:
jdk7 中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8中的ArrayList的对象的创建类似于单例的懒汉式,延迟了数组的创建,节省内存.
LinkedList源码分析:
- LinkedList list= new LinkedList();内部声明 Node first和Node last 两个属性.默认值为null
- list.add(123);//将123封装到Node中,创建了Node对象.
- 其中Node定义为:体现了LinkedList的双向链表的说法.
- 链表很灵活,不存在扩容了.
List接口中的方法
- void add(int index,Object ele):在index位置插入ele元素.
- boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
- Object get(int index):获取指定index位置的元素.
- int indexOf(Object obj):返回obj在集合中首次出现的位置.不存在返回-1.
- int lastindexOf(Object obj):返回obj在集合中末次出现的位置.不存在返回-1
- Object remove(int index):移除指定index位置的元素,并返回此元素.(重载了Collection中的remove方法,所以,remove可以按照对象去删,也可以按照索引去删.)
- 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)
- 改:set(int index,Object ele)
- 查:get(int index)
- 插:add(int index,Object ele)
- 长度:size()
- 遍历:①Iterator②增强for循环③普通循环(有索引)
遍历
方式一:使用迭代器 iterator
方式二:增强for循环
方式三:普通for循环
package List.LinkedList.Method;
import org.junit.Test;
import java.util.*;
class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Person)) return false;
Person person = (Person) o;
return age == person.age && Objects.equals(name, person.name);
}
// @Override
// public int hashCode() {
// return Objects.hash(name, age);
// }
}
public class Demo1 {
@Test
public void test1() {
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("Tom", 12));
list.add(456);
System.out.println(list);
//void add(int index,Object ele):在index位置插入ele元素.
list.add(1, "bb");
System.out.println(list);
//boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
List list1 = Arrays.asList(1, 2, 3);
list.addAll(list1);
System.out.println(list.size());//9
//Object get(int index):获取指定index位置的元素.
System.out.println(list.get(0));
}
@Test
public void test2() {
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("Tom", 12));
list.add(456);
//int indexOf(Object obj):返回obj在集合中首次出现的位置.不存在返回-1
int index = list.indexOf(456);
System.out.println(index);
//int lastindexOf(Object obj):返回obj在集合中末次出现的位置.不存在返回-1
System.out.println(list.lastIndexOf(4567));
//Object remove(int index):移除指定index位置的元素,并返回此元素.(重载了Collection中的remove方法,所以,remove可以按照对象去删,也可以按照索引去删.)
Object obj = list.remove(0);
System.out.println(obj);
System.out.println(list);
//Object set(int index,Object ele):设置指定index位置的元素为ele.
list.set(1, "cc");
System.out.println(list);
//List subList(int fromindex, int toindex):返回从fromindex到toindex位置的左闭右开区间的集合.
List subList = list.subList(2, 4);
System.out.println(list);
System.out.println(subList);
}
@Test
public void test3() {
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
//方式一:Iterator迭代器方式
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//方式二:增强for循环
for (Object o : list) {
System.out.println(o);
}
//方式三:普通for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
Vector源码分析:
- jdk7和jdk8中通过Vector()构造器创建对象时,底层都创建了长度为10的数组.
- 在扩容方面,默认扩容为原来数组长度的2倍.