当前位置:   article > 正文

Java:ArrayList详解_arraylist类用数组实现了什么类和什么类接口

arraylist类用数组实现了什么类和什么类接口

 一、ArrayList简介

在集合框架中,ArrayList是一个普通的类,实现了List接口,具体框架图如下:

22e7d594395d450e87ef91dfaac38748.png

二、ArrayList使用

1、构造方法

不带参数

d15f693a00d54d9cac894ba9274fe521.png

bb9868ada8cf46fd8b25ee09e80af184.png 

没有初始化,默认为空,只是一个数组引用

67e5bfc810904486901d9d5cab67dc1d.png

常量数组,没有分配内存,长度是0 

因此不带参数的构造并没有给数组大小

 带参数

初始化数组大小

1a69d183e16e48e0a22794baaf5da305.png

cc8a295931ac4876ba77361f2d8d12c2.png

如果参数是0的情况下,就会是空数组

如果是参数小于0就会抛出异常 

另一个带一个参数的构造方法

cd9ba9a6e8b44921af440a9690d0302b.png

参数Collection是一个接口,只要是实现了该接口的都可以进行传递

尖括号里的‘?’是通配符,尖括号里面可以写E或者E的子类

举例:

  1. public static void main(String[] args) {
  2. ArrayList<Integer> arrayList = new ArrayList<>();
  3. ArrayList<Integer> arrayList1 = new ArrayList<>(arrayList);
  4. }

 ArrayList实现了Collection接口,arrayList1的Integer是arrayList的Integer(或者Integer的子类),所以可以传递

2、add

直接尾部增加

bf5ba5060fd14f1596784fa3a6940e5f.png 

95ba275255ee40819505874d11c70871.png

 如果刚开始数组是0,就通过grow方法扩容

176b86bfc7284155892439502382df8c.png 

f60faf1fce4a4084a63082b258cdcb2b.png

如果刚开始数组是0,就进不去if语句,else语句就new数组

数组大小为minCapacity=size+1=1和DEFAULT_CAPACITY=10的最大值

所以当第一次分配内存就是10

8b5a38e563e5450e87ccb9799fc4d034.png

如果刚开始数组不是0,进入if语句,初步预估按照1.5倍大小扩容

如果用户所需大小超过预估1.5倍大小,则按照用户所需大小扩容真正扩容之前检测是否能扩容成功,防止太大导致扩容失败

将element放到指定index位置

5747a575f7374b0aa9701931dab98d8a.png

addAll可以将一组数据一次性添加 

9ef11a8b1b3b4c68bc6c05cf04dad3bc.png

 3、remove

删除指定下标位置

 3ef7e0eaea734148a3c1432b74272803.png

remove删除值,将数据装箱

a4136e91f4814fafbe5988fa91813086.png 

3adde03e58d740f4870cc0346f43f121.png 

4、get

获取下标位置的元素

c37ab1d72dca4fd8be1bf20333c58682.png 

5、set

将下标位置元素设置为element

055a8b6d2a3e48f1b2ce304b78aa05c9.png

6、clear

清空数据

025482ca95a149cab132599b9de87bfe.png

7、contains

判断o是否在线性表中

6d50c572dd85410f8ff6338a1ffe5b96.png 

8、indexOf

返回第一个o所在下标

f795da8bc4f148ed908f08d6ed88c9ac.png

9、lastIndexOf

返回最后一个o的下标

e4326ffe53604df38c5de8ac0c89307f.png 

10、subList

截取部分List,注意截取到的List是直接引用截取的位置,返回的是fromIndex的地址,因此改变新List就会改变原List

71386aba9b0b4247b7794be717a5f032.png

 三、遍历ArrayList

  1. public static void main(String[] args) {
  2. ArrayList<Integer> arrayList = new ArrayList<>();
  3. arrayList.add(10);
  4. arrayList.add(1);
  5. arrayList.add(2);
  6. arrayList.add(4);
  7. System.out.println(arrayList);
  8. System.out.println("=======");
  9. for (int i = 0; i < arrayList.size(); i++) {
  10. System.out.print(arrayList.get(i)+" ");
  11. }
  12. System.out.println();
  13. System.out.println("======");
  14. for (Integer x:arrayList) {
  15. System.out.print(x+" ");
  16. }
  17. System.out.println();
  18. System.out.println("=======");
  19. //迭代器
  20. Iterator<Integer> it = arrayList.iterator();
  21. while(it.hasNext()){
  22. System.out.println(it.next()+" ");
  23. }
  24. System.out.println();
  25. System.out.println("=======");
  26. ListIterator<Integer> it2 = arrayList.listIterator();
  27. while(it2.hasNext()){
  28. System.out.println(it2.next()+" ");
  29. }
  30. System.out.println();
  31. System.out.println("=======");
  32. ListIterator<Integer> it3 = arrayList.listIterator(arrayList.size());//从最后位置打印
  33. while(it3.hasPrevious()){
  34. System.out.println(it3.previous()+" ");
  35. }
  36. System.out.println();
  37. System.out.println("=======");
  38. }

四、优缺点

缺点

1. ArrayList底层使用连续的空间,任意位置插入或删除元素时,需要将该位置后序元素整体往前或者往后搬移,故时间复杂度为O(N)

2. 增容需要申请新空间,拷贝数据,释放旧空间。会有不小的消耗。

3. 增容一般是呈2倍的增长,势必会有一定的空间浪费。例如当前容量为100,满了以后增容到200,我们再继续插入了5个数据,后面没有数据插入了,那么就浪费了95个数据空间。

(链表弥补)

 优点:

适合根据下标进行查找和更新的场景

五、例题

1、简单的洗牌算法

先来创建扑克牌

  1. public class Card {
  2. public int rank;//数字
  3. public String suit;//花色
  4. public Card(int rank,String suit){
  5. this.rank = rank;
  6. this.suit = suit;
  7. }
  8. @Override
  9. public String toString() {
  10. return "{" + rank + " " + suit + "}";
  11. }
  12. }

再来写一副牌的方法,包括创建一副新扑克牌,洗牌,抓牌

  1. import java.util.*;
  2. public class Cards {
  3. public static final String[] suits = {"♥","♠","♣","♦"};
  4. public List<Card> buyCard(){
  5. List<Card> cardList = new ArrayList<>();
  6. for (int i = 0; i < 4; i++) {
  7. for (int j = 1; j <=13 ; j++) {
  8. int rank = j;
  9. String suit = suits[i];
  10. Card card = new Card(rank,suit);
  11. cardList.add(card);
  12. }
  13. }
  14. return cardList;
  15. }
  16. //洗牌,两两交换
  17. public void shuffle(List<Card> cardList){
  18. Random random = new Random();
  19. for(int i = cardList.size()-1;i>0;i--){
  20. int rand = random.nextInt(i);
  21. Card tmp = cardList.get(i);
  22. cardList.set(i,cardList.get(rand));
  23. cardList.set(rand,tmp);
  24. }
  25. }
  26. //轮流抓牌
  27. public void drawCards(List<Card> cardList){
  28. List<Card> hand1 = new ArrayList<>();
  29. List<Card> hand2 = new ArrayList<>();
  30. List<Card> hand3 = new ArrayList<>();
  31. List<List<Card>> hands = new ArrayList<List<Card>>();//列表里有三个人摸得牌,每个人手里的牌都放到列表里,相当于二维数组
  32. hands.add(hand1);
  33. hands.add(hand2);
  34. hands.add(hand3);
  35. for (int i = 0; i < 5; i++) {
  36. for (int j = 0;j < 3;j++){
  37. Card card =cardList.remove(0);//删除0下标表示抓牌
  38. hands.get(j).add(card);
  39. }
  40. }
  41. System.out.println("第一个人的牌:"+hand1);
  42. System.out.println("第二个人的牌:"+hand2);
  43. System.out.println("第三个人的牌:"+hand3);
  44. }
  45. }
  1. import java.util.List;
  2. public class test {
  3. public static void main(String[] args) {
  4. Cards cards = new Cards();
  5. List<Card> cardList = cards.buyCard();//得到一副牌
  6. System.out.println(cardList);
  7. //洗牌
  8. System.out.println("洗牌");
  9. cards.shuffle(cardList);
  10. System.out.println(cardList);
  11. //抓牌
  12. System.out.println("抓牌");
  13. cards.drawCards(cardList);
  14. System.out.println("剩下的牌");
  15. System.out.println(cardList);
  16. }
  17. }

结果

d2a5e343abf546458a118c3423961e49.png 2、杨辉三角

  1. public List<List<Integer>> generate(int numRows){
  2. List<List<Integer>> ret = new ArrayList<>();
  3. List<Integer> list = new ArrayList<Integer>();
  4. list.add(1);
  5. ret.add(list);
  6. for (int i = 1; i < numRows; i++) {
  7. List<Integer> curRow = new ArrayList<>();
  8. //第一个
  9. curRow.add(1);
  10. //中间
  11. for (int j = 1; j < i; j++) {
  12. List<Integer> preRow = ret.get(i-1);
  13. int x1 = preRow.get(j);
  14. int x2 = preRow.get(j-1);
  15. curRow.add(x1+x2);
  16. }
  17. //最后一个
  18. curRow.add(1);
  19. ret.add(curRow);
  20. }
  21. return ret;
  22. }
  23. public static void main(String[] args) {
  24. List<List<Integer>> list = generate(6);
  25. for(int i =0;i< list.size();i++){
  26. for (int j = 0; j < list.get(i).size(); j++) {
  27. System.out.print(list.get(i).get(j)+" ");
  28. }
  29. System.out.println();
  30. }
  31. }

d1a0b267e39a4223953472a56b4ca687.png 

3、删除两字符串相同的字符

删除第一个字符串当中所有字符串2中所有的字符,使用ArrayList

  1. public static List<Character> func(String str1,String str2){
  2. List<Character> list = new ArrayList<>();
  3. for (int i = 0; i < str1.length(); i++) {
  4. char ch = str1.charAt(i);
  5. if(!str2.contains(ch+"")){
  6. list.add(ch);
  7. }
  8. }
  9. return list;
  10. }
  11. public static void main(String[] args) {
  12. System.out.println("str1:"+"hello every");
  13. System.out.println("str2:"+"hey");
  14. List<Character> list = func("hello everyone","hey");
  15. for (char x:list) {
  16. System.out.print(x);
  17. }
  18. System.out.println();
  19. }

798ec0321b324b4187da0082009d34a0.png 

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/766347
推荐阅读
相关标签
  

闽ICP备14008679号