一、list接口
1.1List简介
List接口是Collection的子接口,实现List接口的容器类中的元素是有顺序的,而且可以重复。
List容器中的元素都对应一个整数型的序号记录其在容器中的位置,可以根据此序号存取元素。
主要实现类有 ArrayList 和 LinkedList。
1.2List接口中的方法
相对Collection接口扩展的方法
Object get(int index);
通过索引获取元素
Object set(int index,Object element);
修改某出索引元素
void add(int index,Object element);
在某处索引添加元素
Object remove(int index);
根据索引删除元素
示例代码
public class Demo01_ArrayList { public static void main(String[] args) { List<String> list = new ArrayList<String>(); //添加数据 list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("ddd"); list.add("aaa"); //元素个数 System.out.println("list中的元素个数为:"+list.size()); System.out.println(list); // list是有序的(和添加时的顺序相同) for(String s:list){ System.out.println(s); } //根据索引获取元素 System.out.println("第2个元素为:"+list.get(1)); System.out.println("第6个元素为:"+list.get(5)); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } System.out.println(list.indexOf("aaa")); System.out.println(list.indexOf("bbb")); System.out.println(list.lastIndexOf("bbb")); System.out.println(list.lastIndexOf("aaa")); list.add(1,"xxx"); //在指定位置添加一个元素,后面的元素依次后移 System.out.println(list); list.set(1,"yyy"); // 在指定位置添加一个元素,替换原有的元素 System.out.println(list); list.remove("aaa"); //只会移除第一个aaa System.out.println(list); list.remove(0); //移除指定位置的元素 System.out.println(list); } }
-
删除list中全部元素
for(String str:list){ list.remove(str); // 增强型for循环不允许调用remove方法删除元素 } //直接调用Collection中的Clear即可 list.clear();
1.3ArrayList的使用
java.util.ArrayList
集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList
是最常用的集合。
许多程序员开发时非常随意地使用ArrayList完成任何需求,并不严谨,这种用法是不提倡的。
1.4LinkedList
java.util.LinkedList
集合数据存储的结构是链表结构。方便元素添加、删除的集合。
LinkedList是一个双向链表,那么双向链表是什么样子的呢,我们用个图了解下
实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法。这些方法我们作为了解即可:
-
public void addFirst(E e)
:将指定元素插入此列表的开头。 -
public void addLast(E e)
:将指定元素添加到此列表的结尾。 -
public E getFirst()
:返回此列表的第一个元素。 -
public E getLast()
:返回此列表的最后一个元素。 -
public E removeFirst()
:移除并返回此列表的第一个元素。 -
public E removeLast()
:移除并返回此列表的最后一个元素。 -
public boolean isEmpty()
:如果列表不包含元素,则返回true。
LinkedList是List的子类,List中的方法LinkedList都是可以使用,这里就不做详细介绍,我们只需要了解LinkedList的特有方法即可。
public class LinkedListDemo { public static void main(String[] args) { LinkedList<String> link = new LinkedList<String>(); //添加元素 link.addFirst("abc1"); link.addFirst("abc2"); link.addFirst("abc3"); System.out.println(link); // 获取元素 System.out.println(link.getFirst()); System.out.println(link.getLast()); // 删除元素 System.out.println(link.removeFirst()); System.out.println(link.removeLast()); } }
面试常考
ArrayList与LinkedList的区别?
-
他们都是线性表,但是ArrayList基于数组(顺序存储),LinkedList基于链表(链式存储)
-
由于实现的不同,ArrayList在随机访问元素时性能较高,插入和删除元素时效率较低,LinkedList则反之。
二、Vector和Stack(栈)
1.1Vector的使用
Vector: 描述的是一个线程安全的ArrayList。
-
Vector与ArrayList的区别
ArrayList: 多线程效率高。
Vector : 多线程安全的,所以效率低。
-
常用方法
void addElement(E obj)
在集合末尾添加元素
E elementAt( int index)
返回指定角标的元素
Enumeration elements()
返回集合中的所有元素,封装到Enumeration对象中
Enumeration接口:
boolean hasMoreElements()
测试此枚举是否包含更多的元素。
E nextElement()
如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。
示例代码
public static void main(String[] args) { Vector v = new Vector(); v.addElement("aaa"); v.addElement("bbb"); v.addElement("ccc"); System.out.println( v ); System.out.println( v.elementAt(2) ); // ccc // 遍历Vector遍历 Enumeration ens = v.elements(); while ( ens.hasMoreElements() ){ System.out.println( ens.nextElement() ); } }
1.2Stack(栈)
Stack类是Vector类的子类。特点是先进后出。
常用方法:
boolean | empty() 测试堆栈是否为空。 |
---|---|
E | peek() 查看堆栈顶部的对象,但不从堆栈中移除它。 |
E | pop() 移除堆栈顶部的对象,并返回该对象作为此函数的值。 |
E | push(E item) 把项压入堆栈顶部。 |
int | search(Object o) 返回对象在堆栈中的位置,以 1 为基数。 |
示例代码
public class Demo03_Stack { public static void main(String[] args) { Stack<String> st = new Stack<>(); st.push("aaa"); st.push("bbb"); st.push("ccc"); st.push("ddd"); System.out.println(st.peek()); // 获取栈顶元素,但不移除 System.out.println(st.peek()); System.out.println(st.pop()); // 弹出栈顶元素 --- 获得栈顶元素,并将其从栈中移除 System.out.println(st); System.out.println(st.isEmpty()); System.out.println(st.search("aaa")); // 自顶向下找,从1开始数 } }
1.3可变参数(扩展)
在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化成如下格式:
修饰符 返回值类型 方法名(参数类型... 形参名){ }
其实这个书写完全等价与
修饰符 返回值类型 方法名(参数类型[] 形参名){ }
只是后面这种定义,在调用时必须传递数组,而前者可以直接传递数据即可。
JDK1.5以后。出现了简化操作。... 用在参数上,称之为可变参数。
同样是代表数组,但是在调用这个带有可变参数的方法时,不用创建数组(这就是简单之处),直接将数组中的元素作为实际参数进行传递,其实编译成的class文件,将这些元素先封装到一个数组中,在进行传递。这些动作都在编译.class文件时,自动完成了。
代码演示:
public class ChangeArgs { public static void main(String[] args) { int[] arr = { 1, 4, 62, 431, 2 }; int sum = getSum(arr); System.out.println(sum); // 6 7 2 12 2121 // 求 这几个元素和 6 7 2 12 2121 int sum2 = getSum(6, 7, 2, 12, 2121); System.out.println(sum2); } /* * 完成数组 所有元素的求和 原始写法 public static int getSum(int[] arr){ int sum = 0; for(int a : arr){ sum += a; } return sum; } */ //可变参数写法 public static int getSum(int... arr) { int sum = 0; for (int a : arr) { sum += a; } return sum; } }