赞
踩
在Java的集合框架中,ArrayList类是List接口的一个具体实现类,其继承框架图如下:
说明:
构造方法 | 解释 |
---|---|
ArrayList() | 无参构造 |
ArrayList(int initialCapacity) | 指定初始容量 |
ArrayList(Collection<? extends E>) | 利用其它Collection初始化 |
import java.util.ArrayList; public class Test { public static void main(String[] args) { // 构造方法一: 无参构造 ArrayList<Integer> list = new ArrayList<>(); System.out.println(list); // 构造方法二: 初始化容量 ArrayList<String> list2 = new ArrayList<>(20); list2.add("hello"); list2.add("world"); System.out.println(list2); // 构造方法三: 利用别的Collection初始化 ArrayList<String> list3 = new ArrayList<>(list2); // 此时list3与list2中存储元素一致 System.out.println(list3); } }
方法 | 解释 |
---|---|
boolean add(E e) | 在末尾加入元素e |
void add(int index, E element) | 在指定位置index处插入元素element |
boolean addAll(Collection<? extends E> c) | 在末尾加入集合c的所有元素 |
boolean addAll(int index, Collection<? extends E> c) | 在指定位置index处插入集合c所有元素 |
@Test public void test_add() { ArrayList<Integer> list = new ArrayList<>(); // 1. add(E e)方法的使用 list.add(1); list.add(2); list.add(3); System.out.println(list); // 2. add(int index, E element)方法的使用 list.add(1, 4); System.out.println(list); // 3. addAll(Collection<? extends E> c)方法的使用 ArrayList<Integer> tmp = new ArrayList<>(); tmp.add(10); tmp.add(20); list.addAll(tmp); // 将tmp集合元素全部添加到list末尾 System.out.println(list); // 4. addAll(int index, Collection<? extends E> c) list.addAll(2, tmp); // 将tmp集合元素全部添加到指定下标 System.out.println(list); }
运行效果如下:
方法 | 解释 |
---|---|
E remove(int index) | 删除指定下标元素 |
boolean remove(Object o) | 删除第一个指定元素 |
boolean removeAll(Collection<?> c) | 删除所有集合c内的元素 |
boolean retainAll(Collection<?> c) | 只保留所有集合c内的元素 |
void clear() | 清空ArrayList |
@Test public void test_remove() { ArrayList<Integer> list = new ArrayList<>(); // 创建集合 list.addAll(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); // asList方法可以看做构建一个集合 System.out.println(list); // 1. remove(int index)方法的使用 list.remove(0); System.out.println(list); // 2. remove(Object o)方法的使用 list.remove(Integer.valueOf(5)); System.out.println(list); // 3. removeAll(Collection<?> c) ArrayList<Integer> tmp = new ArrayList<>(); tmp.add(2); tmp.add(3); list.removeAll(tmp); System.out.println(list); // 4. retainAll(Collection<?> c) ArrayList<Integer> tmp2 = new ArrayList<>(); tmp2.add(4); tmp2.add(6); list.retainAll(tmp2); System.out.println(list); // 5. clear() list.clear(); System.out.println(list); }
注意:
运行效果如下:
方法 | 解释 |
---|---|
E set(int index, E element) | 修改指定下标位置元素为element |
@Test
public void test_modify() {
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
System.out.println(list);
// E set(int index, E element)方法
list.set(1, 100);
System.out.println(list);
}
运行效果如下:
方法 | 解释 |
---|---|
E get(int index) | 获得指定下标的元素 |
boolean contains(Object o) | 查询列表中是否存在元素o |
int indexOf(Object o) | 返回列表中第一个o元素下标 |
int lastIndexOf(Object o) | 返回从后往前第一个o元素下标 |
int size() | 返回列表有效元素个数 |
boolean isEmpty() | 判断列表是否为空 |
@Test public void test_search() { ArrayList<String> list = new ArrayList<>(); list.add("Java"); list.add("Spring"); list.add("JavaWeb"); list.add("Spring"); list.add("SpringBoot"); list.add("Mybatis"); list.add("redis"); // 1. E get(int index) System.out.println(list.get(2)); // 2. boolean contains(Object o) System.out.println(list.contains("redis")); // 3. int indexOf(Object o) System.out.println(list.indexOf("Spring")); // 4. int lastIndexOf(Object o) System.out.println(list.lastIndexOf("Spring")); // 5. int size() System.out.println(list.size()); // 6. boolean isEmpty() System.out.println(list.isEmpty()); }
运行效果如下:
方法 | 解释 |
---|---|
List subList(int fromIndex, int toIndex) | 返回指定区间的子列表 |
注意:
该方法参数区间为左闭右开,即[fromIndex, toIndex)
该方法返回类型为List,而不是ArrayList
该方法返回的子列表如果涉及修改操作,则会直接影响原先列表中的值,举例如下
@Test public void test_subList() { // 构建原列表 ArrayList<String> srcList = new ArrayList<>(); srcList.add("MySQL"); srcList.add("Linux"); srcList.add("Docker"); srcList.add("redis"); // 构建子列表 List<String> subList = srcList.subList(1, 3); System.out.println(subList); // 尝试修改subList中的元素 subList.set(0, "Spring"); System.out.println(subList); //打印子列表 System.out.println(srcList); // 打印原列表 }
程序运行结果如下:
@Test
public void test_traverse_forIndex() {
// for循环加下标遍历
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
@Test
public void test_traverse_forEach() {
// 增强for循环遍历
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
for (int elem : list) {
System.out.println(elem);
}
}
@Test
public void test_traverse_iterator() {
// 迭代器遍历
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
Iterator<Integer> iter = list.iterator();
while (iter.hasNext()) {
int elem = iter.next();
System.out.println(elem);
}
}
ArrayList是一个在插入元素过程中自动扩容的顺序表,其源码实现如下:
// 部分成员变量 Object[] elementData; // 存放元素的空间 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // 默认空间 private static final int DEFAULT_CAPACITY = 10; // 默认容量大小 // 无参构造方法 public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } // add方法 public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } // edsureCapacityInternal方法 private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } ensureExplicitCapacity(minCapacity); } // ensureExplicitCapacity方法 private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } // grow方法 private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
扩容流程分析(以无参构造为例):①、当通过无参构造器初始化ArrayList对象时,属性ElementData
指向空对象DEFAULTCAPACITY_EMPTY_ELEMENTDATA
②、调用add方法时,调用ensureCapacityInternal
方法检查容量,传递参数size + 1
即所需最小空间 ③、在ensureCapacityInternal
方法中,判断如果是第一次调用add方法,就申请当前minCapacity
和默认容量DEFAULT_CAPACITY
其中更大值作为申请空间大小,然后调用ensureExplicitCapacity
方法。④、在方法ensureExplicitCapacity
中,判断当前所需空间minCapacity
是否超过当前数组容量,如果超过则调用grow
方法进行扩容 ⑤、在grow
方法中,newCapacity
是1.5倍扩容后的大小最后调用Arrays.copyOf()
进行扩容
总结:
grow()
方法扩容Arrays.copyOf
方法简单洗牌小案例我们模拟用户斗地主时的场景,可以将洗牌过程抽象为如下几个步骤
package CardDemo; import java.util.ArrayList; public class Player { private String name; private ArrayList<Poker.Card> cardList; // 牌组 public Player(String name) { this.name = name; this.cardList = new ArrayList<>(); } // 给玩家发牌方法 public void distributeCards(ArrayList<Poker.Card> cards) { // 从剩余牌中随机选择一张 int randomIndex = (int) (Math.random() * cards.size()); cardList.add(cards.get(randomIndex)); cards.remove(randomIndex); } @Override public String toString() { return "Player{" + "name='" + name + '\'' + ", cardList=" + cardList + '}'; } }
package CardDemo; import java.util.ArrayList; import java.util.Collections; // 扑克牌类 public class Poker { private ArrayList<Card> cards; // 扑克牌 private static final String[] suits = {"♥", "♠", "♣", "♦"}; private static final String[] faces = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"}; // 内部类:单张牌 static class Card { public String face; // 牌面值 public String suits; // 花色值 public Card(String face, String suits) { this.face = face; this.suits = suits; } @Override public String toString() { return face + ":" + suits; } } // 初始化扑克牌 public Poker() { cards = new ArrayList<>(); generateCards(); } // 生成扑克牌函数 public void generateCards() { for (int i = 0; i < suits.length; i++) { for (int j = 0; j < faces.length; j++) { cards.add(new Card(suits[i], faces[j])); } } } // 洗牌方法 public void shuffleCards() { // 调用Collections.shuffle方法 Collections.shuffle(cards); } // 返回扑克牌 public ArrayList<Card> getCards() { return this.cards; } }
package CardDemo; import java.util.ArrayList; public class Test { public static void main(String[] args) { // 生成一副扑克牌并打乱 Poker poker = new Poker(); poker.shuffleCards(); // 洗牌 ArrayList<Poker.Card> cards = poker.getCards(); // 生成四个用户 Player player1 = new Player("玩家一"); Player player2 = new Player("玩家二"); Player player3 = new Player("玩家三"); Player player4 = new Player("玩家四"); Player[] players = {player1, player2, player3, player4}; // 循环给玩家发牌 int index = 0; while (cards.size() > 0) { players[index].distributeCards(cards); index = (index + 1) % players.length; } // 打印每个玩家的牌 System.out.println(player1); System.out.println(player2); System.out.println(player3); System.out.println(player4); } }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。