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() {
    }
}