import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**1.list源码框架
* \------Collection接口:单列集合,用来存储一个一个对象(对于基本类型可以以包装类的形式去存储)
* \----List接口:有序,可重复。--->“动态数组”--长度可以改变 ,替换原有的数组
* \----ArrayList:作为List接口的主要实现类;线程不安全,效率高。底层使用Object[]存储。
* \----LinkedList:对于频繁的插入和删除,比ArrayList效率高, 底层使用双向链表存储。
* \----Vector:作为List的古老实现类;线程安全,效率低。底层使用Object[]存储。
* 2.ArryList的源码分析:
* 2.1jdk 7情况下
* ArrayList list = new ArrayList();底层创建了长度为10的Object[]数组。
* 比如:list.add(123);//elementData[0] = new Integer(123);
* ...
* list.add(11);//如果此次的添加导致底层elementData数组容量不够,则扩容。
* 默认情况下,扩容维原来的1.5倍,同时需要将原有数组中的数据复制到新的数组中。
* 结论:建议开发中使用带参的构造器:AyyayList list = new ArrayList(int capacity)//避免扩容
* 2.2jdk 8 中ArrayList的变化:
* ArrayList list = new ArrayList();//底层Object[] elementData{},并没有创建长度为10的数组
* list.add(123);//第一次调用add()时,底层才创建了长度为10的数组,并将数据123添加到elementData[0]
* ...
* 后续的添加和扩容与jdk 7无异。
* 2.3 小结:8=懒汉(需要的时候再造,延迟了数组的创建过程,节省内存)
* 7中ArrayList的对象的创建类似于单例模式的饿汉式
*
* 3.LinkedList的源码分析:
* LinkedList list = new LinkedList();
*
* 面试:ArrayList LinkedList Vector 三者的异同
* 同:三个类都实现了List接口,存储数据的特点相同:有序,可重复的
* 异:
* @author 冀帅
* @date 2020/8/10-17:21
*/
public class ListTest {
@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);//[123, 456, AA, Person{name='Tom', age=12}, 456]
//1.void add(int index,Object ele):在index位置插入ele元素
list.add(1,"BB");//把BB插入到索引为1的位置
System.out.println(list);//[123, BB, 456, AA, Person{name='Tom', age=12}, 456]
//2.addAll():把list1中的三个元素全部添加到list集合中
List list1 = Arrays.asList(1, 2, 3);
list.addAll(list1);
System.out.println(list.size());//9
//3.Object get(int index):获取指定index位置的元素
System.out.println(list.get(1));//BB
}
@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);
//4.indexOf(Object obj):返回obj在当前集合中首次出现的位置
System.out.println(list.indexOf(456));//1
System.out.println(list.indexOf(789));//-1,不存在就返回-1
//5.int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
System.out.println(list.lastIndexOf(456));//4
System.out.println(list.lastIndexOf(789));//-1,不存在就返回-1
//6.Object remove(int index):移除指定index位置的元素,并返回此元素
Object o = list.remove(0);
System.out.println(o);//123 返回删除的元素
System.out.println(list);//[456, AA, Person{name='Tom', age=12}, 456]
//7.Object set(int index,Object ele):设置指定index位置的元素为ele
list.set(1,"CC");
System.out.println(list);//[456, CC, Person{name='Tom', age=12}, 456]
//8.List sublist(int formIndex,int toIndex):返回从formIndex到toIndex位置的子集合(左闭右开)
System.out.println(list.subList(1, 3));//[CC, Person{name='Tom', age=12}],不会对本身的list造成影响
}
/*
*总结:常用方法
*增:add(Object obj)//末尾增加元素
*删:remove(int index)/remove(Object obj)-->Collection中的
*改:set(int index,Object ele)
*查:get(int index)
*插:add(int index,Object ele)//在某位位置插入元素
*长度:size()
*遍历:1.Iterator迭代器方式
* 2.增强for循环
* 3.普通的循环
*
*
* */
@Test
// 9.遍历
public void test3(){
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add("AA");
list.add(new Person("Tom",12));
list.add(456);
// 方式一:迭代器
Iterator iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("--------------------------");
// 方式二:增强for循环
for (Object o : list) {
System.out.println(o);
}
System.out.println("--------------------------");
// 方式三:普通循环
for (int i = 0; i <list.size() ; i++) {
System.out.println(list.get(i));
}
}
}
/**
* @author 冀帅
* @date 2020/8/7-15:31
*/
public class Person {
private String name;
private int 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 boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
}