Java ArrayList与示例
在Java编程语言中,创建数组时,必须提供其长度。创建数组后,数组的长度是固定的,并且该长度不能更改。在许多情况下,我们可能不知道高级的确切长度,在这种情况下,可以在Java中使用ArrayList。
Java中的ArrayList类
Java中的ArrayList是List接口的可调整大小的数组实现,驻留在java.util包中。由于ArrayList是动态的,因此它可以自动增长或者收缩。
在内部,ArrayList使用以初始容量创建的数组。如果由于添加了元素而达到了该容量,则会创建一个新阵列,其容量比旧阵列的容量大50%,并将现有元素复制到该新阵列中。从ArrayList中删除元素时,以同样的方式自动填充在基础数组中创建的间隙。作为用户,从我们这里可以了解到增加或者减少ArrayList长度的逻辑。
请参阅Java中的ArrayList内部实现以了解有关Java中ArrayList的内部实现的更多信息。
Java中ArrayList的功能
这篇文章中讨论的ArrayList的一些功能如下:
ArrayList是Java Collections框架的一部分。 ArrayList扩展了AbstractList类,并实现了List,RandomAceess,Cloneable和Serializable接口。
创建ArrayList时,我们可以为其提供容量或者使用默认容量10.
由于Java中的ArrayList实现RandomAccess接口,因此可以通过将元素的索引传递给方法来随机访问列表的元素。索引从列表中的0开始。
Java中的ArrayList只能存储对象,如果需要存储原始数据类型,则必须使用包装器类。由于使用了自动装箱,即使将原语包裹在幕后,它也可以自动发生。
我们可以将NULL添加到ArrayList。
也允许将重复的元素添加到ArrayList中。
Java中的ArrayList不是线程安全的。
ArrayList的iterator和listIterator方法返回的迭代器是快速失败的。这意味着,如果在创建迭代器之后的任何时间对列表进行结构修改,则除了通过迭代器自己的remove或者add方法之外,该迭代器都会抛出ConcurrentModificationException。
Java ArrayList构造函数
ArrayList()–此构造函数创建一个初始容量为10(默认容量)的空列表。
ArrayList(int initialCapacity)–此构造函数构造一个具有指定初始容量的空列表。
ArrayList(Collection <?extends E> c)–构造一个包含指定集合元素的列表,其顺序由集合的迭代器返回。
Java示例创建ArrayList
让我们看一个创建ArrayList并将元素添加到其中的示例。在代码的后面,这些元素也被打印出来。
import java.util.ArrayList; import java.util.List; public class ArrayListDemo { public static void main(String[] args) { List<String> nameList = new ArrayList<String>(); // adding elements nameList.add("Adam"); nameList.add("Amy"); nameList.add("Jim"); // Adding at specific index nameList.add(0, "Leo"); // Displaying list elements for(String name : nameList){ System.out.println("Name- " + name); } } }
输出:
Name- Leo Name- Adam Name- Amy Name- Jim
如我们所见,使用此语句创建了默认容量的ArrayList。
List<String> nameList = new ArrayList<String>();
现在,所有Collections类都是通用的,因此我们可以在开始时指定要在列表中存储的元素类型。本示例中使用的列表只能存储字符串。
然后将一些元素添加到列表中,其中一个元素添加到特定索引处。之后,使用for-each循环显示元素。
ArrayList类中的方法
这是Java中ArrayList类中的一些方法的列表。
add(int index,E element)–此方法将传递的元素插入此列表中的指定位置。
add(E e)–此方法将指定的元素添加到此列表的末尾。
addAll(int index,Collection <?扩展E> c)–此方法从指定位置开始将传递的集合中的所有元素插入此列表。
addAll(Collection <?extends E> c)–此方法将指定集合中的所有元素添加到此列表的末尾,以指定集合的Iterator返回它们的顺序。
clear()–从此列表中删除所有元素的方法。
contains(Object o)–如果此列表包含指定的元素,则返回true。
get(int index)–返回此列表中指定位置的元素。
indexOf(Object o)–返回此列表中指定元素的首次出现的索引;如果此列表不包含该元素,则返回-1.
isEmpty()–如果此列表不包含任何元素,则返回true。
iterator()–以正确的顺序返回此列表中元素的迭代器。
lastIndexOf(Object o)–返回此列表中指定元素的最后一次出现的索引;如果此列表不包含该元素,则返回-1.
remove(int index)–删除此列表中指定位置的元素。
remove(Object o)–从列表中删除第一次出现的指定元素(如果存在)。
removeIf(Predicate <?super E> filter)–删除此集合中满足给定谓词的所有元素。
set(int index,E element)–用指定的元素替换此列表中指定位置的元素。
size()–返回此列表中的元素数。
ArrayList允许重复值和null
在ArrayList中,我们可以添加重复的元素,也可以多次允许null。
import java.util.ArrayList; import java.util.List; public class ArrayListDemo { public static void main(String[] args) { List<String> nameList = new ArrayList<String>(); // adding elements nameList.add("Adam"); nameList.add("Amy"); nameList.add(null); nameList.add("Jim"); nameList.add("Jim"); nameList.add(null); // Displaying list elements for(String name : nameList){ System.out.println("Name- " + name); } System.out.println("Size of the list- " + nameList.size()); } }
输出:
Name- Adam Name- Amy Name- null Name- Jim Name- Jim Name- null Size of the list- 6
Java示例,从ArrayList中删除元素
下面的示例演示如何使用remove()方法从Java ArrayList中删除任何元素。
public class ArrayListDemo { public static void main(String[] args) { List<String> nameList = new ArrayList<String>(); // adding elements nameList.add("Adam"); nameList.add("Amy"); nameList.add("Jim"); nameList.add("Leo"); // removing using index nameList.remove(2); // Displaying list elements for(String name : nameList){ System.out.println("Name- " + name); } System.out.println("--------------------------"); // removing using object nameList.remove("Leo"); // Displaying list elements for(String name : nameList){ System.out.println("Name- " + name); } } }
输出:
Name- Adam Name- Amy Name- Leo ------------------------- Name- Adam Name- Amy
将原始数据类型添加到ArrayList
Java中的ArrayList只能存储对象,如果需要存储原始数据类型,则必须将它们包装在相应的包装器类中才能获得对象。使用自动装箱,该过程现在是自动完成的,而且在后台完成。
如果要将int添加到ArrayList
public class ArrayListDemo { public static void main(String[] args) { List<String> nameList = new ArrayList<String>(); // Wrapping int in Integer wrapper class numList.add(new Integer(5)); // Done automatically numList.add(6); for(Integer num : numList){ System.out.println("Number- " + num); } } }
输出:
Number- 5 Number- 6
在代码中,我们可以看到将原始数据类型添加到ArrayList的两种方法。在添加第一个元素时,将int包装在Integer包装器类中。在第二个添加中,它是自动完成的。
另请注意,在for-each循环中,我们正在将元素分配给Integer变量,这不会对第二个元素造成任何问题,因为第二个元素会自动包装以获取Integer对象。
Java ArrayList迭代器
在ArrayList中使用迭代器,我们可以按顺序遍历列表。我们可以使用iterator()方法获取一个Iterator,并使用listIterator()方法获取ListIterator。 Iterator和ListIterator之间的区别在于ListIterator允许沿任一方向遍历列表。
请参考不同的方法来迭代Java中的ArrayList,以查看不同的选项来迭代Java中的ArrayList。
由iterator和listIterator方法返回的迭代器都是快速失败的。如果在创建迭代器之后的任何时间对列表进行结构修改,除非通过迭代器自己的remove或者add方法,否则迭代器将抛出ConcurrentModificationException。请注意,List迭代器提供了add和remove方法,而Iterator接口仅提供了remove()方法。
Java ArrayList迭代器示例
public class ArrayListDemo { public static void main(String[] args) { List<String> nameList = new ArrayList<String>(); // adding elements nameList.add("Adam"); nameList.add("Amy"); nameList.add("Jim"); nameList.add("Leo"); // getting iterator Iterator<String> itr = nameList.iterator(); while(itr.hasNext()){ System.out.println("Name- " + itr.next()); nameList.add("Hyman"); } } }
输出:
Name- Adam Exception in thread "main" java.util.ConcurrentModificationException at java.util.ArrayList$Itr.checkForComodification(Unknown Source) at java.util.ArrayList$Itr.next(Unknown Source) at com.theitroad.ArrayListDemo.main(ArrayListDemo.java:20)
在进行迭代的代码中,尝试使用列表的add方法(结构修改)添加元素,这就是抛出ConcurrentModificationException的原因。
使用迭代器的remove方法的示例代码
public class ArrayListDemo { public static void main(String[] args) { List<String> nameList = new ArrayList<String>(); // adding elements nameList.add("Adam"); nameList.add("Amy"); nameList.add("Jim"); nameList.add("Leo"); // getting iterator Iterator<String> itr = nameList.iterator(); while(itr.hasNext()){ String name = itr.next(); if(name.equals("Jim")){ // using iterators remove method itr.remove(); } } for(String name : nameList){ System.out.println("Name- " + name); } } }
输出:
Name- Adam Name- Amy Name- Leo
该代码可以正常工作,因为修改是使用迭代器的remove方法完成的。
ArrayList不是线程安全的
Java中的ArrayList不是线程安全的。如果ArrayList的一个实例在多个线程之间共享,并且任何线程都在结构上修改了List,则其他线程可能无法获取更新后的列表。在这种情况下,必须使用Collections.synchronizedList()方法从外部同步ArrayList。
例如
List<String> tempList = Collections.synchronizedList(nameList);