Java ArrayList与示例

时间:2020-01-09 10:35:00  来源:igfitidea点击:

在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);