java基础:13.2 集合框架 - ArrayList
List 接口继承自Collection 接口, 定义了一个用于顺序存储元素的合集。
可以使用它的两个具体类 [ 线性表类-- ArrayList ] 或者 [ 链表类 - LinkedList ] 来创建一个线性表( list ) 。
1、ArrayList
在 java基础:6.0 ArrayList 中,初步了解了ArrayList
,知道了ArrayList的特点:
- ArrayList 的大小灵活,所以无须提前给定它的大小。而当创建一个数组时,它的大小必须给定。
- ArrayList 包含许多有用的方法。比如,可以使用contains 方法来测试某个元素是否在列表中。如果使用数组,则需要编写额外代码来实现该方法。
- 元素必须是一种对象,不能是int,double…,可以是Integer.
- ArrayList 可以用来存储多个自定义的对象
{
...
ArrayList<String> cityList = new ArrayList<>();
// <>中的元素必须是一种对象,不能是int,double..,可以是Integer.
cityList.add("London");
...
cityList.add("Miami");
System.out.println(cityList.Size() + cityList.contains("Miami") + cityList.remove("Miami");
System.out.println(cityList.toString()); // == System.out.println(cityList);
}
2、特点
ArrayList用数组存储元素,但是动态创建的。超出限制时会增加50%容量,用System.arraycopy()复制到新的数组中。
因此最好能给出数组大小的预估值。默认第一次插入元素时创建大小为10的数组。
LinkedList 在一个链表( linked list) 中存储元素。
要选用这两种类中的哪一个依赖于特定需求。
如果只需要按下标随机访问元素,而不会在线性表中插入或删除元素,ArrayList的效率很高!
通过 list.get(i),或者 list.set(1,“London”) 这两个方法可直接访问和修改;
直接通过list.add(“China”);在线性表末尾加元素的性能也很好,这是ArrayList的优点。
但是,如果按下标插入、删除元素–add(i,e), remove(i), remove(e),
则要用System.arraycopy()来移动部分受影响的元素,性能就变差了!!!这是ArrayList的缺点。
ArrayList 不能自动减小。可以使用方法 trimToSize() 将数组容量减小到线性表的大小。
3、和数组的区别
4、常用的方法
(可以参考上一节Collection总结的方法)
toArray
可以把一个ArrayList对象转换为数组。
需要注意的是,如果要转换为一个Hero数组,那么需要传递一个Hero数组类型的对象给toArray(),这样toArray方法才知道,你希望转换为哪种类型的数组,否则只能转换为Object数组。
ArrayList heros = new ArrayList();
// 初始化5个对象
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero " + i));
}
Hero specialHero = new Hero("special hero");
heros.add(specialHero);
System.out.println(heros);
Hero hs[] = (Hero[])heros.toArray(new Hero[]{});
System.out.println("数组:" + hs);
addAll
把另一个容器所有对象都加进来.
heros.addAll(anotherHeros);
5、使用泛型与不使用泛型
学习别人的程序时发现有人是第一种写法,有人是第二种。
-
ArrayList heros = new ArrayList();
对于不使用泛型的容器,可以往里面放英雄,也可以往里面放物品
heros.add(new Hero(“盖伦”));
heros.add(new Item(“冰杖”)); // 放别的类的对象并不会报错 -
ArrayList<Hero> heros = new ArrayList<>();
使用泛型后, heros.add(new Item(“冰杖”));则会系统报错,因此此时只可以放属性是Hero的对象,或者Hero的子类 -
如果要求ArrayList只能放两种对象,则可以把这两个对象继承在同一个父类。利用了2中的知识点。
6、遍历
有三种方法。
for
用for循环遍历
iterator
迭代器遍历
for:
用增强型for循环
package collection;
import java.util.ArrayList;
import java.util.Iterator;
public class TestCollection {
public static void main(String[] args) {
ArrayList<Hero> heros = new ArrayList<>();
// 初始化5个对象
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero " + i));
}
Hero specialHero = new Hero("special hero");
heros.add(specialHero);
System.out.println(heros);
// 第一种遍历 for循环
System.out.println("--------for 循环-------");
for (int i = 0; i < heros.size(); i++) {
Hero h = heros.get(i);
System.out.println(h);
}
//第二种遍历,使用迭代器
System.out.println("--------使用while的iterator-------");
Iterator<Hero> it= heros.iterator();
//从最开始的位置判断"下一个"位置是否有数据
//如果有就通过next取出来,并且把指针向下移动
//直到"下一个"位置没有数据
while(it.hasNext()){
Hero h = it.next();
System.out.println(h);
}
//迭代器的for写法
System.out.println("--------使用for的iterator-------");
for (Iterator<Hero> iterator = heros.iterator(); iterator.hasNext();) {
Hero hero = (Hero) iterator.next();
System.out.println(hero);
}
// 第三种,增强型for循环
System.out.println("--------增强型for循环-------");
for (Hero h : heros) {
System.out.println(h);
}
}
}
7、练习
练习1 -判断是否相同
如果就是要判断集合里是否存在一个 name等于 "hero 1"的对象,应该怎么做?
疑问 为什么方法1和方法2的答案不一样???
package collection;
import java.util.ArrayList;
public class TestCollection {
public static void main(String[] args) {
ArrayList<Hero> heros = new ArrayList<>();
// 初始化5个对象
for (int i = 0; i < 5; i++) {
heros.add(new Hero("hero " + i));
}
Hero specialHero = new Hero("special hero");
heros.add(specialHero);
System.out.println(heros);
Hero testhero = new Hero("hero 1");
for(Hero h: heros) {
if ( h.getName() == testhero.getName() )
System.out.println("存在");
else System.out.println("不存在");
}
System.out.println("方法2");
for(int i=0 ; i<heros.size(); i++) {
if(heros.get(i).toString().equals("hero 2"))
System.out.println("存在");
}
}
}
练习2 - 首先初始化一个Hero集合,里面放100个Hero对象,名称分别是从
hero 0
hero 1
hero 2
…
hero 99.
通过遍历的手段,删除掉名字编号是8的倍数的对象
public class TestCollection {
public static void main(String[] args) {
ArrayList<Hero> heros = new ArrayList<>();
// 初始化5个对象
for (int i = 0; i < 100; i++) {
heros.add(new Hero("hero " + i));
}
for(int i=0; i < heros.size();i++) {
int n = Integer.parseInt(heros.get(i).getName().substring(5));
if( n%8 ==0 )
heros.remove(i);
}
for(Hero a:heros)
System.out.println(a);
}
}