Java编程基础中的ArrayList用于存储动态大小的元素集合。与大小固定的数组相反,ArrayList会在添加新元素时自动增大其大小。
ArrayList是Java集合框架的一部分,它实现了Java的List
接口。
以下几点需要注意Java中的ArrayList -
ArrayList是一个可调整大小的数组,也称为动态数组。它的尺寸越来越大,以适应新的元素,并在元素被移除时缩小尺寸。
ArrayList内部使用数组来存储元素。就像数组一样,它允许您通过索引来检索元素。
Java ArrayList允许重复值和空值。
Java ArrayList是一个有序的集合。它维护元素的插入顺序。
您不能创建原始类型,如一个ArrayList int
,chat
等你需要用盒装的类型,如Integer
,Character
,Boolean
等。
Java ArrayList不同步。如果多个线程同时尝试修改ArrayList,那么最终结果将是非确定性的。如果多个线程要修改它,你必须显式同步对ArrayList的访问。
这个例子显示:
ArrayList()
构造函数创建ArrayList 。add()
方法向ArrayList添加新元素。import java.util.ArrayList;
import java.util.List;
public class CreateArrayListExample {
public static void main(String[] args) {
// Creating an ArrayList of String
List<String> animals = new ArrayList<>();
// Adding new elements to the ArrayList
animals.add("Lion");
animals.add("Tiger");
animals.add("Cat");
animals.add("Dog");
System.out.println(animals);
// Adding an element at a particular index in an ArrayList
animals.add(2, "Elephant");
System.out.println(animals);
}
}
输出
[Lion, Tiger, Cat, Dog]
[Lion, Tiger, Elephant, Cat, Dog]
这个例子显示:
如何使用ArrayList(Collection c)
构造函数从另一个ArrayList创建一个ArrayList 。
如何使用该addAll()
方法将现有ArrayList中的所有元素添加到新的ArrayList中。
import java.util.ArrayList;
import java.util.List;
public class CreateArrayListFromCollectionExample {
public static void main(String[] args) {
List<Integer> firstFivePrimeNumbers = new ArrayList<>();
firstFivePrimeNumbers.add(2);
firstFivePrimeNumbers.add(3);
firstFivePrimeNumbers.add(5);
firstFivePrimeNumbers.add(7);
firstFivePrimeNumbers.add(11);
// Creating an ArrayList from another collection
List<Integer> firstTenPrimeNumbers = new ArrayList<>(firstFivePrimeNumbers);
List<Integer> nextFivePrimeNumbers = new ArrayList<>();
nextFivePrimeNumbers.add(13);
nextFivePrimeNumbers.add(17);
nextFivePrimeNumbers.add(19);
nextFivePrimeNumbers.add(23);
nextFivePrimeNumbers.add(29);
// Adding an entire collection to an ArrayList
firstTenPrimeNumbers.addAll(nextFivePrimeNumbers);
System.out.println(firstTenPrimeNumbers);
}
}
输出:
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
这个例子显示:
isEmpty()
方法检查ArrayList是否为空。size()
方法找到ArrayList的大小。get()
方法访问ArrayList中特定索引处的元素。set()
方法修改ArrayList中特定索引处的元素。import java.util.ArrayList;
import java.util.List;
public class AccessElementsFromArrayListExample {
public static void main(String[] args) {
List<String> topCompanies = new ArrayList<>();
// Check is an ArrayList is empty
System.out.println("Is the topCompanies list empty? : " + topCompanies.isEmpty());
topCompanies.add("Google");
topCompanies.add("Apple");
topCompanies.add("Microsoft");
topCompanies.add("Amazon");
topCompanies.add("Facebook");
// Find the size of an ArrayList
System.out.println("Here are the top " + topCompanies.size() + " companies in the world");
System.out.println(topCompanies);
// Retrieve the element at a given index
String bestCompany = topCompanies.get(0);
String secondBestCompany = topCompanies.get(1);
String lastCompany = topCompanies.get(topCompanies.size() - 1);
System.out.println("Best Company: " + bestCompany);
System.out.println("Second Best Company: " + secondBestCompany);
System.out.println("Last Company in the list: " + lastCompany);
// Modify the element at a given index
topCompanies.set(4, "Walmart");
System.out.println("Modified top companies list: " + topCompanies);
}
}
输出:
Is the topCompanies list empty? : true
Here are the top 5 companies in the world
[Google, Apple, Microsoft, Amazon, Facebook]
Best Company: Google
Second Best Company: Apple
Last Company in the list: Facebook
Modified top companies list: [Google, Apple, Microsoft, Amazon, Walmart]
这个例子显示:
如何从ArrayList |中删除元素 delete(Object o)
如何删除所有匹配给定谓词|的元素 removeIf()
如何清除ArrayList | clear()
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class RemoveElementsFromArrayListExample {
public static void main(String[] args) {
List<String> programmingLanguages = new ArrayList<>();
programmingLanguages.add("C");
programmingLanguages.add("C++");
programmingLanguages.add("Java");
programmingLanguages.add("Kotlin");
programmingLanguages.add("Python");
programmingLanguages.add("Perl");
programmingLanguages.add("Ruby");
System.out.println("Initial List: " + programmingLanguages);
// Remove the element at index `5`
programmingLanguages.remove(5);
System.out.println("After remove(5): " + programmingLanguages);
// Remove the element "Kotlin" (The remove() method returns false if the element does not exist in the ArrayList)
boolean isRemoved = programmingLanguages.remove("Kotlin");
System.out.println("After remove(\"Kotlin\"): " + programmingLanguages);
// Remove all the elements belonging to the collection scriptingLanguages
List<String> scriptingLanguages = new ArrayList<>();
scriptingLanguages.add("Python");
scriptingLanguages.add("Ruby");
scriptingLanguages.add("Perl");
programmingLanguages.removeAll(scriptingLanguages);
System.out.println("After removeAll(scriptingLanguages): " + programmingLanguages);
// Remove all the elements that satisfy the given predicate
programmingLanguages.removeIf(new Predicate<String>() {
@Override
public boolean test(String s) {
return s.startsWith("C");
}
});
/*
The above removeIf() call can also be written using lambda expression like this -
programmingLanguages.removeIf(s -> s.startsWith("C"))
*/
System.out.println("After Removing all elements that start with \"C\": " + programmingLanguages);
// Remove all elements from the ArrayList
programmingLanguages.clear();
System.out.println("After clear(): " + programmingLanguages);
}
}
输出:
Initial List: [C, C++, Java, Kotlin, Python, Perl, Ruby]
After remove(5): [C, C++, Java, Kotlin, Python, Ruby]
After remove("Kotlin"): [C, C++, Java, Python, Ruby]
After removeAll(scriptingLanguages): [C, C++, Java]
After Removing all elements that start with "C": [Java]
After clear(): []
以下示例显示如何使用迭代遍历ArrayList
forEach
循环。iterator()
。iterator()
和Java 8 forEachRemaining()方法。listIterator()
。import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class IterateOverArrayListExample {
public static void main(String[] args) {
List<String> tvShows = new ArrayList<>();
tvShows.add("Breaking Bad");
tvShows.add("Game Of Thrones");
tvShows.add("Friends");
tvShows.add("Prison break");
System.out.println("=== Iterate using Java 8 forEach loop ===");
tvShows.forEach(tvShow -> {
System.out.println(tvShow);
});
System.out.println("\n=== Iterate using an iterator() ===");
Iterator<String> tvShowIterator = tvShows.iterator();
while (tvShowIterator.hasNext()) {
String tvShow = tvShowIterator.next();
System.out.println(tvShow);
}
System.out.println("\n=== Iterate using an iterator() and Java 8 forEachRemaining() method ===");
tvShowIterator = tvShows.iterator();
tvShowIterator.forEachRemaining(tvShow -> {
System.out.println(tvShow);
});
System.out.println("\n=== Iterate using a listIterator() to traverse in both directions ===");
// Here, we start from the end of the list and traverse backwards.
ListIterator<String> tvShowListIterator = tvShows.listIterator(tvShows.size());
while (tvShowListIterator.hasPrevious()) {
String tvShow = tvShowListIterator.previous();
System.out.println(tvShow);
}
System.out.println("\n=== Iterate using simple for-each loop ===");
for(String tvShow: tvShows) {
System.out.println(tvShow);
}
System.out.println("\n=== Iterate using for loop with index ===");
for(int i = 0; i < tvShows.size(); i++) {
System.out.println(tvShows.get(i));
}
}
}
输出:
=== Iterate using Java 8 forEach loop ===
Breaking Bad
Game Of Thrones
Friends
Prison break
=== Iterate using an iterator() ===
Breaking Bad
Game Of Thrones
Friends
Prison break
=== Iterate using an iterator() and Java 8 forEachRemaining() method ===
Breaking Bad
Game Of Thrones
Friends
Prison break
=== Iterate using a listIterator() to traverse in both directions ===
Prison break
Friends
Game Of Thrones
Breaking Bad
=== Iterate using simple for-each loop ===
Breaking Bad
Game Of Thrones
Friends
Prison break
=== Iterate using for loop with index ===
Breaking Bad
Game Of Thrones
Friends
Prison break
在遍历期间需要修改ArrayList时,iterator()
和listIterator()
方法很有用。
考虑下面的例子,在iterator.remove()
遍历它的时候我们使用方法从ArrayList中移除元素-
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ArrayListIteratorRemoveExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(13);
numbers.add(18);
numbers.add(25);
numbers.add(40);
Iterator<Integer> numbersIterator = numbers.iterator();
while (numbersIterator.hasNext()) {
Integer num = numbersIterator.next();
if(num % 2 != 0) {
numbersIterator.remove();
}
}
System.out.println(numbers);
}
}
输出:
[18, 40]
下面的例子显示了如何:
查找ArrayList |中最后一次出现元素的索引 lastIndexOf()
import java.util.ArrayList;
import java.util.List;
public class SearchElementsInArrayListExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("John");
names.add("Alice");
names.add("Bob");
names.add("Steve");
names.add("John");
names.add("Steve");
names.add("Maria");
// Check if an ArrayList contains a given element
System.out.println("Does names array contain \"Bob\"? : " + names.contains("Bob"));
// Find the index of first occurrence of an element in an ArrayList
System.out.println("indexOf \"Steve\": " + names.indexOf("Steve"));
System.out.println("indexOf \"Mark\": " + names.indexOf("Mark"));
// Find the index of the last occurrence of an element in an ArrayList
System.out.println("lastIndexOf \"John\" : " + names.lastIndexOf("John"));
System.out.println("lastIndexOf \"Bill\" : " + names.lastIndexOf("Bill"));
}
}
输出:
Does names array contain "Bob"? : true
indexOf "Steve": 3
indexOf "Mark": -1
lastIndexOf "John" : 4
lastIndexOf "Bill" : -1
由于ArrayList支持泛型,因此可以创建任何类型的ArrayList 。它可以是简单的类型,如Integer
,String
,Double
或复杂类型等的ArrayLists的ArrayList,或包含HashMap的ArrayList或任何用户定义的对象的ArrayList。
在以下示例中,您将学习如何创建用户定义对象的ArrayList。
import java.util.ArrayList;
import java.util.List;
class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = 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;
}
}
public class ArrayListUserDefinedObjectExample {
public static void main(String[] args) {
List<User> users = new ArrayList<>();
users.add(new User("Rajeev", 25));
users.add(new User("John", 34));
users.add(new User("Steve", 29));
users.forEach(user -> {
System.out.println("Name : " + user.getName() + ", Age : " + user.getAge());
});
}
}
输出:
Name : Rajeev, Age : 25
Name : John, Age : 34
Name : Steve, Age : 29
对ArrayList进行排序是您在程序中遇到的一个非常常见的任务。在本节中,我会告诉你如何 -
Collections.sort()
方法对ArrayList进行排序。ArrayList.sort()
方法对ArrayList进行排序。import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ArrayListCollectionsSortExample {
public static void main(String[] args) {
List<Integer> numbers = new ArrayList<>();
numbers.add(13);
numbers.add(7);
numbers.add(18);
numbers.add(5);
numbers.add(2);
System.out.println("Before : " + numbers);
// Sorting an ArrayList using Collections.sort() method
Collections.sort(numbers);
System.out.println("After : " + numbers);
}
}
输出:
Before : [13, 7, 18, 5, 2]
After : [2, 5, 7, 13, 18]
2.使用ArrayList.sort()方法对ArrayList排序
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class ArrayListSortExample {
public static void main(String[] args) {
List<String> names = new ArrayList<>();
names.add("Lisa");
names.add("Jennifer");
names.add("Mark");
names.add("David");
System.out.println("Names : " + names);
// Sort an ArrayList using its sort() method. You must pass a Comparator to the ArrayList.sort() method.
names.sort(new Comparator<String>() {
@Override
public int compare(String name1, String name2) {
return name1.compareTo(name2);
}
});
// The above `sort()` method call can also be written simply using lambda expressions
names.sort((name1, name2) -> name1.compareTo(name2));
// Following is an even more concise solution
names.sort(Comparator.naturalOrder());
System.out.println("Sorted Names : " + names);
}
}
输出:
Names : [Lisa, Jennifer, Mark, David]
Sorted Names : [David, Jennifer, Lisa, Mark]
3.使用自定义比较器对对象的ArrayList进行排序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
class Person {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class ArrayListObjectSortExample {
public static void main(String[] args) {
List<Person> people = new ArrayList<>();
people.add(new Person("Sachin", 47));
people.add(new Person("Chris", 34));
people.add(new Person("Rajeev", 25));
people.add(new Person("David", 31));
System.out.println("Person List : " + people);
// Sort People by their Age
people.sort((person1, person2) -> {
return person1.getAge() - person2.getAge();
});
// A more concise way of writing the above sorting function
people.sort(Comparator.comparingInt(Person::getAge));
System.out.println("Sorted Person List by Age : " + people);
// You can also sort using Collections.sort() method by passing the custom Comparator
Collections.sort(people, Comparator.comparing(Person::getName));
System.out.println("Sorted Person List by Name : " + people);
}
}
输出:
Person List : [{name='Sachin', age=47}, {name='Chris', age=34}, {name='Rajeev', age=25}, {name='David', age=31}]
Sorted Person List by Age : [{name='Rajeev', age=25}, {name='David', age=31}, {name='Chris', age=34}, {name='Sachin', age=47}]
Sorted Person List by Name : [{name='Chris', age=34}, {name='David', age=31}, {name='Rajeev', age=25}, {name='Sachin', age=47}]
ArrayList类不同步。如果多个线程同时尝试修改一个ArrayList,那么最终的结果变得不确定,因为一个线程可能会覆盖另一个线程所做的更改。
以下示例显示了当多个线程同时尝试修改ArrayList时发生的情况。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class UnsafeArrayListExample {
public static void main(String[] args) throws InterruptedException {
List<Integer> unsafeArrayList = new ArrayList<>();
unsafeArrayList.add(1);
unsafeArrayList.add(2);
unsafeArrayList.add(3);
// Create a thread pool of size 10
ExecutorService executorService = Executors.newFixedThreadPool(10);
// Create a Runnable task that increments the each element of the ArrayList by one
Runnable task = () -> {
incrementArrayList(unsafeArrayList);
};
// Submit the task to the executor service 100 times.
// All the tasks will modify the ArrayList concurrently
for(int i = 0; i < 100; i++) {
executorService.submit(task);
}
executorService.shutdown();
executorService.awaitTermination(60, TimeUnit.SECONDS);
System.out.println(unsafeArrayList);
}
// Increment all the values in the ArrayList by one
private static void incrementArrayList(List<Integer> unsafeArrayList) {
for(int i = 0; i < unsafeArrayList.size(); i++) {
Integer value = unsafeArrayList.get(i);
unsafeArrayList.set(i, value + 1);
}
}
}
上述程序的最终输出应该相等,[101, 102, 103]
因为我们将ArrayList中的值增加了100次。但是如果你运行这个程序,它会在每次运行时产生不同的输出 -[96, 96, 98]
好吧!现在让我们看看我们如何ArrayList
在多线程环境中同步访问。
以下示例显示了上一个示例的同步版本。与以前的程序不同,该程序的输出是确定性的,并且始终是相同的。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class SynchronizedArrayListExample {
public static void main(String[] args) throws InterruptedException {
List<Integer> safeArrayList = Collections.synchronizedList(new ArrayList<>());
safeArrayList.add(1);
safeArrayList.add(2);
safeArrayList.add(3);
// Create a thread pool of size 10
ExecutorService executorService = Executors.newFixedThreadPool(10);
// Create a Runnable task that increments the each element of the ArrayList by one
Runnable task = () -> {
incrementArrayList(safeArrayList);
};
// Submit the task to the executor service 100 times.
// All the tasks will modify the ArrayList concurrently
for(int i = 0; i < 100; i++) {
executorService.submit(task);
}
executorService.shutdown();
executorService.awaitTermination(60, TimeUnit.SECONDS);
System.out.println(safeArrayList);
}
// Increment all the values in the ArrayList by one
private static void incrementArrayList(List<Integer> safeArrayList) {
synchronized (safeArrayList) {
for (int i = 0; i < safeArrayList.size(); i++) {
Integer value = safeArrayList.get(i);
safeArrayList.set(i, value + 1);
}
}
}
}
输出:
[101, 102, 103]
以上示例使用Collections.synchronizedList()
方法来获取ArrayList的同步视图。
而且,对incrementArrayList()
方法内的ArrayList的修改被封装在一个synchronized
块中。这确保了两个线程不能同时增加ArrayList元素。
CopyOnWriteArrayList
如果你需要线程安全,你也可以使用。它是ArrayList类的线程安全版本。它通过创建ArrayList的新副本来实现所有的变异操作。
http://blog.xqlee.com/article/420.html