`
xiao1zhao2
  • 浏览: 38965 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java集合框架:ArrayList<E>

阅读更多

目录

1.常用方法
2.关于遍历
3.关于删除
4.关于删除
5.关于删除
6.关于扩容
7.关于最大容量
8.1.8版本新特性
9.List的其他实现类

 

ArrayList实现了List接口,内部通过Object类型的数组有序存储数据(可重复),并且能够根据元素数量进行扩容,实现了动态的增加和减少元素.

 

1.常用方法

add()

addAll()

增加元素

remove()

removeAll()

clear()

移除元素

contains()

containsAll()

是否包含指定元素

size()

isEmpty()

equals()

元素个数

是否为空

是否为同一个ArrayList

iterator()

toArray()

创建迭代器

将元素返回指定数组

 

2关于遍历
public class ArrayListDemo2 {

	public static void main(String[] args) {

		ArrayList<Integer> list = new ArrayList<>();
		list.add(23);
		list.add(33);
		list.add(64);
		list.add(33);
		list.add(54);
		list.add(89);

		// 重写了toString方法,直接打印输出
		System.out.println(list);
		
		// 通过for循环遍历
		for (int i = 0, j = list.size(); i < j; i++) {
			System.out.println(list.get(i));
		}

		// 通过for each遍历
		for (int value : list) {
			System.out.println(value);
		}

		// 通过迭代器遍历
		Iterator<Integer> car = list.iterator();
		while (car.hasNext()) {
			int value = car.next();
			System.out.println(value);
		}
	}
}

 

3.关于删除
public class ArrayListDemo3 {

	public static void main(String[] args) {
		
		ArrayList<String> list = new ArrayList<>();
		String str1 = new String("Hello");
		String str2 = new String("Hello");
		list.add(str1);
		System.out.println(list.size());
		list.remove(str2);
		System.out.println(list.size());
	}
}

运行结果:

1

0

虽然str1和str2是两个String对象,但是list中的元素被移除了.实际上remove方法内部是通过equals方法判断是否是同一个元素,我们用下面的代码验证:

public class ArrayListDemo3 {

	public static void main(String[] args) {

		ArrayList<Person> list = new ArrayList<>();
		Person p1 = new Person("Hello");
		Person p2 = new Person("World");
		list.add(p1);
		System.out.println(list.size());
		list.remove(p2);
		System.out.println(list.size());
	}
}

class Person {
	String name;
	public Person(String name) {
		this.name = name;
	}
	@Override
	public boolean equals(Object o) {
		System.out.println("我被执行了");
		return true;
	}
}

运行结果:

1

我被执行了

0

 

4.关于删除

我们利用一个ArrayList来存储分数,现在希望将60分以下的删除:

public class ArrayListDemo4 {

	public static void main(String[] args) throws Exception {

		ArrayList<Integer> list = new ArrayList<>();
		list.add(80);
		list.add(54);
		list.add(68);
		list.add(72);
		list.add(49);
		list.add(51);
		list.add(98);
		list.add(77);
		list.add(43);
		list.add(50);

		for (int i = 0; i < list.size(); i++) {
			if (list.get(i) < 60) {
				list.remove(i);
			}
		}

		for (int value : list) {
			System.out.println(value);
		}
	}
}

 运行结果:

80

68

72

51

98

77

50

为什么51和50没有删掉呢?实际上,ArrayList在每次删除一个元素后,后面的元素会向前移动补位.在上述程序中,当我们删除49后,后面的元素向前补位,下一次循环时索引加1,便跳过了51.解决方法:for循环从ArrayList尾部向前遍历. 

		for (int i = list.size() - 1; i >= 0; i--) {
			if (list.get(i) < 60) {
				list.remove(i);
			}
		}

运行结果:

80
68
72
98
77

 

5.关于删除

在上一节中,我们能不能通过for each和Iterator进行操作呢?

		// for each循环
		for (int value : list) {
			if (value < 60) {
				list.remove(new Integer(value));
			}
		}
		// 迭代器
		Iterator<Integer> car = list.iterator();
		while (car.hasNext()) {
			int value = car.next();
			if (value < 60) {
				list.remove(new Integer(value));
			}
		}

两段代码的运行结果一样:java.util.ConcurrentModificationException.抛出了并发修改异常,所以当for each和iterator对一个ArrayList进行迭代时,需保证这个ArrayList不能改变,因为ArrayList是非线程安全的.但是Iterato提供了一个remove方法,可以对ArrayList中的元素进行删除.即:

		Iterator<Integer> car = list.iterator();
		while (car.hasNext()) {
			int value = car.next();
			if (value < 60) {
				car.remove();
			}
		}

运行结果:  
80
68
72
98
77

 

6.关于扩容

每一个ArrayList都有一个容量,即数组Object[] elementData的长度.利用无参构造函数创建一个ArrayList时,会使用默认容量10.当我们向其中不断地增加元素超过容量时,ArrayList会进行扩容.ArrayList的扩容原理:新建一个Object类型的数组,长度为原数组长度*3/2,然后将就数组的值赋给新数组,使elementData指向新数组.通过反射进行验证:

public class ArrayListDemo6 {

	public static void main(String[] args) throws Exception {
		
		ArrayList<Integer> list = new ArrayList<>();
		Class c = Class.forName("java.util.ArrayList");
		Field f = c.getDeclaredField("elementData");
		f.setAccessible(true);
		Object[] data = null;

		// 向list中添加50个元素,输出每次ElementData的长度
		for (int i = 1; i <= 50; i++) {
			list.add(i);
			data = (Object[]) f.get(list);
			System.out.print(data.length + "\t");
			if (i % 10 == 0) {
				System.out.println();
			}
		}
	}
}

 运行结果:

10 10 10 10 10 10 10 10 10 10 
15 15 15 15 15 22 22 22 22 22 
22 22 33 33 33 33 33 33 33 33 
33 33 33 49 49 49 49 49 49 49 
49 49 49 49 49 49 49 49 49 73

如果我们已知要存储数据的容量,尽量在创建ArrayList时为其指定容量,避免其多次扩容而降低性能.另外,ArrayList中还为我们提供了两个针对于控制容量的方法:

trimToSize() 将elementData的长度修整为当前元素个数
ensureCapacity() 设置当前ArrayList容量

 

7.关于最大容量

在ArrayList中,还有一个静态常量MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8,用来限制当前ArrayList的最大容量(理论上可以达到Integer.MAX_VALUE).在每次进行扩容时,会用一个int型数据来存储新的容量:int newCapacity = oldCapacity + (oldCapacity >> 1);当ArrayList中的元素达到MAX_ARRAY_SIZE后再次扩充时,newCapacity经过扩容算法会溢出,导致符号位由0变1,变成负值.ArrayList中的hugeCapacity方法通过判断newCapacity是否发生溢出,关键代码:

	private static int hugeCapacity(int minCapacity) {
		if (minCapacity < 0)
			throw new OutOfMemoryError();
		return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE
				: MAX_ARRAY_SIZE;
	}

所以,当ArrayList达到极限容量时,再次扩容会抛出异常.

 

8.1.8版本新特性

JDK在SE1.8中新增了stream包,并且在Collection中增加了stream()方法,利用其特性我们可以用来进行过滤以及排序等.

public class ArrayListDemo8 {

	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<>();
		Collections.addAll(list, 95, 34, 67, 89, 23, 79, 66, 12, 98);
		list.stream().filter(e -> e > 60).sorted((i1, i2) -> i1 - i2).forEach(System.out::println);
	}
}

上述代码执行功能:过滤掉60及以下的分数→排序→打印输出.
运行结果:
66
67
79
89
95
98

 

9.List的其他实现类

1)Vector

Vector是早期的collection,与ArrayList的区别主要有两点:线程安全,扩容方式*2.

2)LinkedList

双向循环链表,内部元素不是通过数组存储的.而是把每一个元素封装Node<E>,每一个Node有三个属性:

E item; 元素本身
Node<E> next; 指向后一个Node
Node<E> prev; 指向前一个Node

而LinkedList本身只包含两个Node类型的属性first和last,通过Node使元素形成链表,并且是双向的,实现逻辑上的地址连续.在进行插入和删除功能时,性能要优于ArrayList.

3)Stack

对象堆栈.遵循LIFO(Last In First Out)原则,常用方法:

empty() 测试堆栈是否为空
peek() 查看堆栈顶部的对象,但不移除
pop() 移除堆栈顶部的对象,并返回该对象
push() 把对象压入堆栈顶部
search() 返回对象在堆栈中的位置,以1为基数
 
0
0
分享到:
评论
2 楼 xiao1zhao2 2015-04-01  
liujiafei_2007 写道
你好,导致符号位由0变1,这个能不能举个例子?谢谢

int capacity = Integer.MAX_VALUE - 5;
for (int i = 0; i < 10; i++) {
	System.out.println(capacity++);
}

后面输出的是负数,因为溢出了
1 楼 liujiafei_2007 2015-04-01  
你好,导致符号位由0变1,这个能不能举个例子?谢谢

相关推荐

    intent传递ArrayList&lt;T&gt;

    intent 传递 ArrayList&lt;T&gt;

    超市会员管理系统.rar

    所有会员(卡)--集合:List ArrayList&lt;Member&gt; 程序整体流程搭建的方法 循环 分支 验证会员是否存在的方法 集合的遍历,集合元素的查找 系统随机生成会员卡号的方法 Random类 开卡 输入会员信息...

    JNI与C++数据类型传递示例(包括ArrayList对象、ArrayList嵌套返回)

    一个C++(Ubuntu16.04+QT5.9.1)通过JNI,调用JAVA类及方法的示例。通过JNI传递和返回多种类型的参数,boolean ,int,String,ArrayList&lt;string&gt;,ArrayList嵌套ArrayList&lt;ArrayList&lt;String&gt;&gt;等。

    Java集合框架测试

    List&lt;Friend&gt; friends = new ArrayList&lt;Friend&gt;(); List&lt;Friend&gt; classmates = new ArrayList&lt;Friend&gt;(); List&lt;Friend&gt; family = new ArrayList&lt;Friend&gt;(); data.put("我的好友", friends); data.put(...

    arraylist 和 list<T> 效率对比

    Arraylist 和 List&lt;T&gt; 在使用的效率是不一样的,选择不同的集合 能使项目的性能有很大的提高!

    java桑硅谷 day23 晨考.zip

    ArrayList&lt;City&gt; bj = new ArrayList&lt;&gt;(); bj.add(new City(1,"北京市")); ArrayList&lt;City&gt; tj = new ArrayList&lt;&gt;(); tj.add(new City(4,"天津市")); ArrayList&lt;City&gt; hn = new ArrayList&lt;&gt;(); hn.add...

    深入Java集合学习系列(二):ArrayList实现原理

    深入Java集合学习系列(二): ArrayList实现原理

    Java设计二次元动漫人物演出活动小游戏代码.docx

    private static ArrayList&lt;String&gt; characters = new ArrayList&lt;String&gt;(); private static ArrayList&lt;String&gt; actions = new ArrayList&lt;String&gt;(); private static Random random = new Random(); public ...

    mybatis generator Java类方法生成

    List&lt;String&gt; warnings = new ArrayList&lt;String&gt;(); boolean overwrite = true; // 如果这里出现空指针,直接写绝对路径即可。 String genCfg = "D:\\workspace\\actity\\mybatis_generator\\src\\main\\...

    ArrayList.txt

    ArrayList&lt;String&gt; list=new ArrayList&lt;String&gt;(); 2、ArrayList(int initialCapacity)  //这是第三个构造方法,构造了一个指定大小但内容为空的链表。 //initialCapacity参数就是初始容量大小。 //如果你...

    购物车代码

    .println("&lt;table align='center'&gt;&lt;tr&gt;&lt;th&gt;图片&lt;/th&gt;&lt;th&gt;产品名称&lt;/th&gt;&lt;th&gt;产品价格&lt;/th&gt;&lt;th colspan=2&gt;操作&lt;/th&gt;&lt;/tr&gt;"); try { DBaccess db = new DBaccess(); ArrayList&lt;Goods&gt; goods = db.Search...

    跟我学Java-day14-ArrayList集合.pdf

    day14-ArrayList集合 1.ArrayList 1.1ArrayList类概述【理解】 ...ArrayList&lt;String&gt; array = new ArrayList&lt;String&gt;(); //添加元素 array.add("hello"); array.add("world"); array.add("java");

    Java测试题2答案

    DEF&lt;br&gt;A notify()&lt;br&gt;B wait()&lt;br&gt;C notifyAll()&lt;br&gt;D sleep()&lt;br&gt;E.yield()&lt;br&gt;F.synchronized(this)&lt;br&gt;7.构造BufferedInputStream的合适参数是哪个? AC&lt;br&gt;A BufferedInputStream&lt;br&gt;B BufferedOutputStream&lt;br&gt;...

    C#中的集合示例(Array,ArrayList,Hashtable,List)

    C#中的集合示例(Array,ArrayList,Hashtable,List&lt;T&gt;)

    最强大的JAVA分页类

    如果不为空 则调用 public Page getP() 得到实体之后 调用 public ArrayList&lt;Object&gt; getList() 方法 得到 实体中的 数据集合 作为参数 传给 public List showPage(int pageSize,int page,ArrayList&lt;Object&gt; list) ...

    struts 标签 logic:iterate使用 logic:iterate

    DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"&gt;&lt;br&gt;&lt;html&gt;&lt;br&gt; &lt;head&gt;&lt;br&gt; &lt;/head&gt;&lt;br&gt; &lt;body&gt;&lt;br&gt; &lt;table&gt;&lt;br&gt; &lt;tr&gt;&lt;br&gt; &lt;td&gt;&lt;%@ include file="../menu.txt"%&gt;&lt;br&gt; &lt;/td&gt;&lt;br&gt; &lt;/tr&gt;...

    支持多个连接多个数据库的HibernateFactory

    软件说明: &lt;br&gt;只支持Hibernate3.0&lt;br&gt;基本用法:&lt;br&gt;import com.liu.base.StaticHbmQuery;&lt;br&gt;&lt;br&gt;StaticHbmQuery shq = new StaticHbmQuery(\"hibernate.cfg.xml\");&lt;br&gt;&lt;br&gt;......&lt;br&gt;&lt;br&gt;//shq.clear();&lt;br&gt;//...

    飞机大战源代码

    ArrayList&lt;Zidan&gt; zidans = new ArrayList&lt;Zidan&gt;(); boolean isFire = false;//是否冒泡(发射) boolean pass=false; ArrayList&lt;Diji&gt; dijis = new ArrayList&lt;Diji&gt;();//保存所有的敌机 int dicount = 15; ...

    创建一个Computer类

    形如:ArrayList&lt;Computer&gt; cList = new ArrayList&lt;Computer&gt;(); (2)为ArrayList对象(例如:上面的cList)添加3个元素。 (3)模拟用户输入(Scanner对象)编号获取对应的Computer信息,并且输出具体的参数。...

    Java JDK实例宝典

    &lt;br&gt;第1章 Java基础 &lt;br&gt;1.1 转换基本数据类型 &lt;br&gt;1.2 Java的运算符 &lt;br&gt;1.3 控制程序的流程 &lt;br&gt;1.4 计算阶乘 &lt;br&gt;1.5 实现命令行程序 &lt;br&gt;第2章 Java面向对象程序设计 &lt;br&gt;2. 1 复数类 &lt;br&gt;2. 2 equals.chashCode...

Global site tag (gtag.js) - Google Analytics