javacore - chapter5 - 04 - 泛型数组列表、数组中插入元素、数组中删除元素、对象的自动拆箱与自动装箱 - demo 6

在java中允许数组大小在运行过程中进行确定,通过arrayList的类来实现,这个类使用起来有点像数组,但在添加或者删除元素的时候,具有自动调节数组容量的功能,而不需要谓词编写代码。

ArrayList是一个采用类型参数type parameter的泛型类(generic class),为了指定数组列表保存咋元素的对象类型,需要用一堆尖括号将类名括起来加在后面。例如ArrayLIst。这种语法被称为“菱形语法”,因为尖括号就像是一个菱形,可以结合new操作符使用菱形语法,编译器会检查这个比那领、参数或者是方法的泛型类型,然后将这个类型放在<>中,在这个例子中,new ArrayLIst<>()将会赋值一个类型是ArrayList的变量,所以泛型类型为Employee。
数组列表管理着对象引用的一个内部数组。最终,数组的全部空间有可能被用尽,这就展现出数组的魅力:如果调用add且内部数组已经满了,数组列表就会自动创建一个更大的数组,并将所有的数组拷贝到较大的数组中。
如果已经清楚或者能够预估出来数组的需要存储的元素,可以在其填充数组之前调用ensureCapacity方法,分配一个固定大小的内部数组,然后调用100次add,而不用重新分配空间,除此之外,还可以把初始容量传递给ArrayList构造器:
ArrayList staff = new ArrayList<>(100);

注意📢:
分配数组列表,如:new ArrayList<>(100) // capacity is 100
它与新数组分配空间有所不同:new Employee[100] //size is 100
数组列表的容量与数组的大小有一个非常重要的区别。如果为数组分配一个100个元素的存储空间,数组就有100个空位置可以用。而容量为100个元素的数组列表只是拥有保存100个元素的潜力,实际上,重新分配空间的话,将会超过100个,但是再最初,甚至完成初始化构造之后,数组列表根本就不含有任何元素。

访问数组列表元素:
数组列表自动扩容的遍历增加了访问元素语法的复杂度,其原因是ArrayList类并不是Java程序设计语言的一部分,它只是一个由某些人编写并放入标准库的一个实用类。
使用get和set方法实现访问或者改变数组元素的操作,而不能使用[]语法格式

数组中插入元素

在数组中插入元素,可以县创建一个数组,然后往里面添加所有元素,然后使用toArray方法将数组元素拷贝到一个数组中。除了在数组列表的尾部追加以外,还可以在数组列表的中间插入元素,使用带索引参数的add方法。为了插入一个新元素,例如在数组的第n位插入一个元素,位于n位之后的所有元素都要像后面移动一位,如果插入新元素后,数组列表的大小超过了容量,数组列表就会被重新分配存储空间。

数组中删除元素

同样,可以对数组中的元素进行删除操作,如果从n位置删除一个元素,位于这个元素之后的元素都需要前移一位,并且数组的大小减1.对于数组实施插入和删除元素的操作效率比较低。对于小型数组来说,这一点不必担心,但是如果数组的存储元素比较多,又要经常在中间位置插入、删除元素,就应该考虑使用链表了,可以使用“for each”循环遍历数组别表。

把Employee[] 替换成了ArrayList 数组变化

  1. 不必指出数组的大小
  2. 使用add将任意多的元素添加到数组中
  3. 使用size()替代length计算元素的数量
  4. 使用a.get(i)替代a[i]访问元素

代码demo如下:

package corejava.chapter5;

import corejava.chapter5.extendsPackage.Employee;

import java.util.ArrayList;

/**
 * @Auther WangYu
 * @Date 2022/3/6
 * 数组的测试类
 */
public class ArrayListTest {
    public static void main(String[] args) {
        ArrayList<Employee> staff = new ArrayList<>();

        staff.add(new Employee("CC", 2000, 2022, 12, 12));
        staff.add(new Employee("DD", 3000, 2022, 12, 12));
        staff.add(new Employee("EE", 4000, 2022, 12, 12));

        for (Employee employee : staff) {
            employee.raiseSalary(200);
        }
        for (Employee employee : staff) {
            System.out.println("name = " + employee.getName() + "salary" + employee.getSalary() + "hireDay:" + employee.getHireDay());
        }
    }
}

对象的自动拆箱与自动装箱

有时候,需要将int这样的基本类型转化为对象,所有的基本类型都有一个与之对应的包装类型,例如,Integer类对应的基本类型为int。通常,这些类被称为包装器wrapper,这些独享包装器类拥有很明显的名字。对象包装器类是不可以变的,即一旦构造了包装器,就不允许更改包装在其中的值。同时,对象包装器还是final,因此不能定义它们的子类。
假设想定义个整形数组列表,而尖括号中的类型参数不允许是基本类型,也就是说不能写成ArrayList,这里就是用到了Integer类型的这种包装类。可以声明为一个Interger类型的数组列表:ArrayList list = new ArrayList<>;

注意:由于每个值分别包装在独享中,所以ArrayList的效率远远小于int[]数组,因此,应该用它来构建小型集合,其原因是此时程序员操作的方便性要比执行效率更加重要。

自动装箱要求boolean、byte、char <=127,介于-128~127之间的short和int也被包装在固定的对象中,例如,如果在前面的例子中将a和b初始化为100,它们进行比较的结果一定成立。

关于自动装箱的说明:

  1. 由于自动包装器引用可以为null,所以自动装箱可能会抛出一个NUllPointerException,这时候需要对可能为空的情况进行特殊处理,避免这种NPE出现。
  2. 如果在一个表达式中混合使用Integer好Double类型,Integer值就会拆箱,提升为double,再装箱成为Double。
  3. 拆箱和装箱是编译器人可以的,而不是虚拟机,编译器在生成类的字节码时候,插入必要的方法调用。虚拟机只是执行这些字节码而已。
  4. 使用数值对象包装器的好处是,可以将某些基本方法防止在包装器中,例如,讲一个数组字符串转化成数值。
    要想让一个字符串转化成为一个整形,可以用下面这种方式:
    int x -= Integer.parseInt(str);
    这里与Integer类型对象没有任何关系,parseInt是一种静态方法,但是Integer类是放置这个方法的一个好地方。

包装器不可以修改数组参数

有些人认为包装器可以用来实现数组参数的修改,这种理解是错误的,在java中方法都是值传递,所以不可能编写一个能够增加整形参数值的方法。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值