04 JavaSE-- 数组、Arrays 类、Collection、Map、

数组

  • 数组是一种引用数据类型,存储方法和实例一样.
  • 数组隐式继承 Object。因此数组也可以调用 Object 类中的方法。
  • 根据数组初始化方式不同分类:静态数组,动态数组。
  • Java 数组存储元素的特点?
    • 数组长度一旦确定不可变。
    • 数组中元素数据类型一致,每个元素占用空间大小相同。
    • 数组中每个元素在空间存储上,内存地址是连续的。
    • 每个元素有索引,首元素索引 0,以 1 递增。
    • 以首元素的内存地址作为数组对象在堆内存中的地址。
    • 所有数组对象都有 length 属性用来获取数组元素个数。

1. 数组的创建

变量的初始化,实际上是三步完成的:声明 + 分配内存 + 赋值

  1. 声明(Declaration):这是定义变量类型的步骤,告诉编译器变量的名称和类型。

  2. 分配内存(Allocation):完成了变量的声明后,这一步由 JVM 自动进行
    在这个阶段,对于基本数据变量,JVM 会为其在中分配内存,但暂时还没有值绑定;
    对于引用类型变量,JVM 会为这个变量 (实例) 的引用在中分配空间,但是不会在中分配空间来存储变量 (实例) 的实际内容。

  3. 赋值(Assignment):给变量一个具体的值,当变量被赋值后,它就被初始化了。

int a;
a = 10;

// 当然,也可以合并为一步
int a = 10;

1.1 声明数组

// 尽管两种方法完全相同,但第二种方法是沿袭 C/CPP 中的用法,应当使用第一种正宗 Java 语法
dataType[] arrayRefVar;   // 首选的方法
//或
dataType arrayRefVar[];  // 效果相同,但不是首选方法

double[] myArraySample;  

1.2 初始化数组

初始化就是给元素分配内存,//并为每个元素赋初始值//。

/** 
 * 1) 声明了一个数据类型为 dataType,引用名为 arrayRefVar 的数组
 * 2) 使用 dataType[arraySize] 实例化一个数组。
 * 3) 把新创建的数组的引用赋值给变量 arrayRefVar。
 */
dataType[] arrayRefVar = new dataType[arraySize];

1.3 静态/动态初始化

  • 静态初始化:由我们为每一个数组元素设置初始值, JVM 根据输入元素的个数,自动决定数组的长度;
  • 事前知道需要存储哪些数据,选用静态初始化。
dataType[] arrayRefVar = new dataType[]{元素1,元素2,,元素n,};

int[] nums = new int[]{1,2,3};	

// 省略 new 版
int[] nums = {1,2,3};	

// 两步版
int[] nums;
nums = new int[]{1,2,3};
  • 动态初始化:由我们来设置数组的长度,而每一个数组元素的初始值由 JVM 来决定。可以看到,与静态初始化完全相反。
  • 事前不知道需要存储哪些数据,只能使用动态初始化。
dataType[] arrayRefVar = new dataType[ length ];

int[] nums = new int[5];

// 两步版
int[] nums;
nums = new int[5];

1.4 遍历数组

使用 for/ for-each/迭代器 皆可完成数组的遍历

1.5 扩容数组

数组长度一旦确定不可变。

为了扩容,只能用其他方法曲线救国

  • 创建一个更大的数组将原数组中的数据全部拷贝到新数组中
    • 使用 System.arraycopy() 方法完成数组的拷贝。
    static int[] biggerArray(int[] oldArr) {
        
        int[] newArr = new int[oldArr.length * 2];
        // 第一个参数是原数组,第三个参数是新数组,第四个参数是复制元素的个数
        // 第二个参数选择原数组的起始位置,第四个参数选择新数组的起始位置
        System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);

        return newArr;
    }

2. 二维数组

多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组。

// 可以看作总共有 2 个特殊的一维数组,每个特殊的一维数组内有 3 个元素
// 也可以看作 2 行 3 列的矩阵, 但是这种思想升到高维数组好就不好想象了.
int[][] a = new int[2][3];

3. Arrays 类的常用方法

  • Arrays 类提供的都是静态方法,这意味着在需要时,可以直接通过 Arrays.方法名 调用,而不用先实例化一个 Arrays 对象

fill 为数组填充同一元素

  • fill 只能为数组填充相同值的元素
Arrays.fill(int[] arr, int data)

// 在数组下标 ( fromIndex,toIndex ) 区间内填充同一元素
Arrays.fill(int[] a, int fromIndex, int toIndex, int val)

sort 数组排序

Arrays.sort(int[] arr)
Arrays.sort(int[] arr,int fromIndex, int toIndex)

Arrays.sort(String[] arr)
Arrays.sort(String[] arr, int fromIndex, int toIndex)

// 基于分治的归并排序算法,支持多核CPU排序,适合大数据量排序
Arrays.parallelSort(int[] arr)方法:
  • 传入整形数组时,sort 方法底层采用快排实现
  • sort 方法支持对字符串内的字符进行排序
  • 对字符串内的字符进行排序时,默认区分大小写,此时大写字母在前
  • 对字符串内的字符进行排序时,可以不区分大小写,而是严格按照字母表顺序排序
	String[] strArray = new String[] { “z”, “a”,C};
    Arrays.sort(strArray);
    //输出: [C, a, z]

	Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
    //输出: [a, C, z]

toString 转字符串

  • 对于 Object 原生的 toString 方法,其比较是对象的引用(对象的地址)是否相等
  • Arrays 类重写了 toString方法,以字符串的形式输出数组中的每个元素
   int[] arr = {3,2,1,5,4};
    System.out.print(arr);//直接将数组打印输出
    //输出:[I@7852e922 (数组的地址)

	String str = Arrays.toString(arr); // Arrays类的toString()方法能将数组中的内容全部打印出来
	//System.out.print(str);
	//输出:[3, 2, 1, 5, 4]

equals 判断数组内元素是否相同

  • 对于 Object 原生的 equals 方法,其比较是对象的引用(对象的地址)是否相等
  • Arrays 类重写了 equals 方法,以判断两个数组内的元素是否完全相同
	int[] arr1 = {1,2,3};
	int[] arr2 = {1,2,3};
	System.out.println(Arrays.equals(arr1,arr2));
	System.out.println(arr1.equals(arr2));

	//输出:true / false
	//前者比较数组内的元素是否完全相等;后者比较的是两个数组对象的地址,两个不同的数组地址当然不同。

数组转 List asList

  • 传入的数组必须是引用数据类型
/**从源码来看, asList 接收的是一个泛型变长参数
 * 而 8 种基本类型是不能泛型化的,要想作为泛型参数就要使用其所对应的包装类。
 * 
 * 再分析 listA 的 Size 为什么是 1 :
 * listA 传递的是一个 int 类型的数组,int 是基本类型不能泛型化
 * 但数组是一个引用类型,它是可以泛型化的,
 * 也就是说例子中是把一个 int 类型的数组本身作为了 T 的类型,将数组自身,而非数组内的元素,存进了 list。
 * 后边 ListA1 与 ListB 也就可以理解了,一个是进行了自动打包,一个是本来就是包装类型。
 */
        int[] intArray = {1,2,3};
        Integer[] integerArray = {1,2,3};

        List listA = Arrays.asList(intArray);
        List listA1 = Arrays.asList(1,2,3);
        List listB = Arrays.asList(integerArray);

        System.out.println(listA.size());//out:1
        System.out.println(listA);// out:intArray 数组的地址[[I@7affc159]
        System.out.println(listA1.size());//out:3
        System.out.println(listB.size());//out:3
  • 任何对数组/ List 实例的改动都会反过来影响到对方
	// asList 返回的 List 实例,其底层与原数组共享相同的数据。
    String[] str = new String[] { "apple", "avocado" };
    List list = Arrays.asList(str);

    str[0] = "pear";
    System.out.println(list); //out : pear,avocado
  • 【阿里开发手册】
    asList 方法返回一个固定大小的 List 对象,且该 List 对象不能使用修改 List 相关的方法。

说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。 因此调用 add/remove/clear 方法会抛出 UnsupportedOperationException 异常

Arrays.asList 体现的是适配器模式,只是转换接口,后台的数据仍是数组。

/**Arrays 的 asList 方法使用的 ArrayList类是一个内部定义的类,而不是 java.util.ArrayList 类。
 * 这个静态内部类中,将存储数组元素的变量设定为 final,
 * 由此判断,这个静态内部类是不能做任何内部元素的添加删除操作的
 * 其次,这个内部类里并没有 add,remove 方法,自然,调用 add 方法不可能成功
 */
 String[] str = new String[] { "apple", "avocado" };
 List list = Arrays.asList(str);
 
// 报运行时异常 UnsupportedOperationException 。
list.add("pear");

想要修改修改 asList 方法返回的 List 对象,可以尝试以下方法:
方法一:在 asList 方法外包一层 ArrayList ,将 Arrays.asList 方法返回的 List 对象转换为一个真正的 java.util.ArrayList 对象

String[] arr = new String[]{"apple", "avocado"};
List<String> list = new ArrayList<>(Arrays.asList(arr));
list.add("pear"); // 正常运行
System.out.println(list); //out : apple,avocado,pear

方法二:使用 Collections 类
我们也可以使用 Collections 类提供的静态方法,将 Arrays.asList() 方法返回的 List 对象转换为一个可修改的List对象

String[] arr = new String[]{"apple", "avocado"};
List<String> list = new ArrayList<>(Arrays.asList(arr));
Collections.addAll(list, "pear"); // 正常运行
System.out.println(list); //out : apple,avocado,pear

binarySearch 二分查找法找指定元素的下标

  • 使用的前提是:数组必须有序

copyOf 截取数组

int[] arr = {10,20,30,40,50};
	int[] arr1 = Arrays.copyOf(arr, 3);
	String str = Arrays.toString(arr1); // Arrays类的toString()方法能将数组中的内容全部打印出来
	System.out.print(str);
	//输出:[10, 20, 30] (截取arr数组的3个元素赋值给新数组arr1)
	
int []arr = {10,20,30,40,50};
	int []arr1 = Arrays.copyOfRange(arr,1,3);
	String str = Arrays.toString(arr1); // Arrays类的toString()方法能将数组中的内容全部打印出来
	System.out.print(str);
	//输出:[20, 30] (从第1位(0开始)截取到第3位(不包括))

Collection

Map

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值