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