Java ArrayList学习

Java中的ArrayList用于存储动态调整大小的元素集合。与固定大小的数组相反,当向其添加新元素时,ArrayList会自动增加其大小。

ArrayList是Java的收集框架的一部分,并实现Java的List接口。

 

以下是有关Java中ArrayList的几点注意事项-

  • ArrayList是可调整大小的数组,也称为动态数组。它会增加其大小以容纳新元素,并在删除元素时缩小其大小。

  • ArrayList在内部使用数组存储元素。就像数组一样,它允许您按元素索引检索元素。

  • Java ArrayList允许重复和空值。

  • Java ArrayList是一个有序集合。它保持元素的插入顺序。

  • 您不能创建基本类型的像一个ArrayList intchar等你需要用盒装的类型,如IntegerCharacterBoolean等。

  • Java ArrayList不同步。如果多个线程尝试同时修改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);

	}
}
# Output
[Lion, Tiger, Cat, Dog]
[Lion, Tiger, Elephant, Cat, Dog]

从另一个集合创建一个ArrayList

此示例显示:

  • 如何使用ArrayList(Collection c)构造函数从另一个集合创建ArrayList 。

  • 如何使用该addAll()方法将现有集合中的所有元素添加到新的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);
	}
}
# Output
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

从ArrayList访问元素

此示例显示:

  • 如何使用该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 if 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);
	}
}
# Output
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中删除元素

此示例显示:

  1. 如何删除ArrayList中给定索引处的元素。remove(int index)

  2. 如何从ArrayList中删除元素。remove(对象o)

  3. 如何从ArrayList中删除给定集合中存在的所有元素。移除所有()

  4. 如何删除与给定谓词匹配的所有元素| removeIf()

  5. 如何清除ArrayList 明确()

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 first occurrence of the given element from the ArrayList
		// (The remove() method returns false if the element does not exist in the
		// ArrayList)
		boolean isRemoved = programmingLanguages.remove("Kotlin");
		System.out.println(isRemoved);
		System.out.println("After remove(\"Kotlin\"): " + programmingLanguages);

		// Remove all the elements that exist in a given collection
		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);
	}
}
# Output
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

下面的示例显示如何使用来遍历ArrayList

  1. Java 8forEach和lambda表达式。
  2. iterator()
  3. iterator()和Java 8 forEachRemaining()方法。
  4. listIterator()
  5. 简单的for-each循环。
  6. 带索引的for循环。
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 and lambda ===");
		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));
		}
	}
}
# Output
=== Iterate using Java 8 forEach and lambda ===
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);
	}
}
# Output
[18, 40]
 

在ArrayList中搜索元素

以下示例显示了如何:

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 the 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"));
	}
}
# Output
Does names array contain "Bob"? : true
indexOf "Steve": 3
indexOf "Mark": -1
lastIndexOf "John" : 4
lastIndexOf "Bill" : -1

用户定义对象的ArrayList

由于ArrayList支持泛型,因此您可以创建任何类型的ArrayList 。它可以是简单类型喜欢IntegerStringDouble或复杂类型等的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());
		});
	}
}
# Output
Name : Rajeev, Age : 25
Name : John, Age : 34
Name : Steve, Age : 29

排序ArrayList

对ArrayList进行排序是您在程序中会遇到的非常常见的任务。在本节中,我将向您展示如何-

  • 使用Collections.sort()方法对ArrayList进行排序。
  • 使用ArrayList.sort()方法对ArrayList进行排序。
  • 使用自定义比较器对用户定义对象的ArrayList进行排序。

1.使用Collections.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);
	}
}
# Output
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
		// expression
		names.sort((name1, name2) -> name1.compareTo(name2));

		// Following is an even more concise solution
		names.sort(Comparator.naturalOrder());

		System.out.println("Sorted Names : " + names);
	}
}
# Output
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);
	}
}
# Output
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,则最终结果将变得不确定,因为一个线程可能会覆盖另一线程所做的更改。

演示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 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倍。但是,如果您运行该程序,则每次运行它都会产生不同的输出-

# Output
[96, 96, 98]

尝试多次运行以上程序,看看它如何产生不同的输出。要了解有关多线程程序中此类问题的更多信息,请查看有关Java并发问题和线程同步的文章

演示如何将并发修改同步到ArrayList的示例

好吧!现在让我们看看如何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 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);
			}
		}
	}
}
# Output
[101, 102, 103]

上面的示例使用Collections.synchronizedList()方法来获取ArrayList的同步视图。

而且,对incrementArrayList()方法内部的ArrayList的修改被包装在一个synchronized块中。这样可以确保没有两个线程可以同时增加ArrayList元素。

CopyOnWriteArrayList如果需要线程安全,也可以使用a 。它是ArrayList类的线程安全版本。它通过创建ArrayList的新副本来实现所有的变异操作。

结论

那是所有人。在本文中,您学习了什么是ArrayList,如何创建ArrayList,如何从ArrayList中添加,修改和删除元素,如何在ArrayList上进行迭代,如何对ArrayList进行排序以及如何同步对ArrayList的访问。 。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值