java(二维)数组知识点

1、数组的声明、初始化

先回顾一下两种数据类型:

  • 基本数据类型:int, short,double, float,long,char,byte,boolean;(8种)
  • 引用数据类型:类,接口,数组,String等

可以看到数组属于引用类型。

1.1)数组变量的定义(声明):
dataType[] arrayRefVar;   // 首选的方法
或
dataType arrayRefVar[];  // 效果相同,但不是首选方法
示例:
int[] arr;

注:建议使用 dataType[] arrayRefVar 的声明风格声明数组变量。 dataType arrayRefVar[] 风格是来自 C/C++ 语言 ,在Java中采用是为了让 C/C++ 程序员能够快速理解java语言。

说明:

Java语言中声明数组时不能指定其长度(数组中元素的个数),这是因为数组是一种引用类型的变量,因此使用它定义一个变量时,仅仅表示定义了一个引用变量(也就是定一个了一个指针),这个引用变量还未指向任何有效的内存,所以定义数组时不能指定数组的长度。而且由于定义数组仅仅只是定一个引用变量,并未指向任何有效的内存空间,所以还没有内存空间来存储数组元素,因此这个数组也不能使用,只有在数组进行初始化后才可以使用。

1.2)数组初始化:

Java中使用关键字new创建数组对象,根据初始化方式不同有两种格式:(静态、动态初始化)

数组类型[] 数组名= new 数组类型[]{元素1,元素2,…,元素n,};
或
数组类型[] 数组名= new 数组类型[length];

一旦使用new关键字为数组分配了内存空间,每个内存空间存储的内容就是数组元素的值。也就是说不可能只分配内容空间而不赋初始值,即使自己在创建数组对象(分配内容空间)时没有指定初始值,系统也会自动为其分配。

int[] a = new int[]{1, 2, 3}; //静态初始化
System.out.println(Arrays.toString(a)); //[1, 2, 3]

int[] b = new int[6]; //动态初始化
System.out.println(Arrays.toString(b)); //[0, 0, 0, 0, 0, 0]

b = a; //同类型的数组变量可以赋值(改变引用地址)
System.out.println(Arrays.toString(b)); //[1, 2, 3]

a[0] = 9; //通过下标修改数组元素
b[1] = 0;
System.out.println(Arrays.toString(b)); //[9, 0, 3]

说明:

  • 数组必须先初始化,才能使用,因为初始化是表示在内存中分配空间;(所谓初始化就是给元素分配内存,并为每个元素赋初始值)
  • 初始化数组有两种方式,静态初始化和动态初始化;
  • 但是无论以哪中方式,一旦初始化完成,数组的长度就固定了,不能再改变,除非重新初始化。也就说数组是定长的!

1)静态初始化

静态初始化特点:由我们为每一个数组元素设置初始值,而数组的长度由系统(JVM)来决定(简单来说就是不指定数组长度)

语法格式:

数组类型[] 数组名= new 数组类型[]{元素1,元素2,…,元素n,};
如:
    int[] nums = new int[]{1,2,3};	
或:
    int[] nums ;
	nums = new int[]{1,2,3,4};	

简化格式:

数组类型[] 数组名 = {元素1,元素2,…,元素n,};
如:
int[] nums = {1,2,3};

注意:在简化格式中,声明后必须立刻初始化,不能先声明后初始化;以下这种方式是错误的!

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

2)动态初始化

动态初始化特点:由我们来设置数组元素的个数(数组长度),而每一个数组元素的初始值由系统来决定(比如int数组,默认值0)。

语法格式:

数组类型[] 数组名= new 数组类型[ length ];

看一个例子:

int[] b = new int[6]; //动态初始化
System.out.println(b.length); //6
System.out.println(Arrays.toString(b)); //[0, 0, 0, 0, 0, 0]

3)静态初始化和动态初始化不能混用:

int arr[] = new int[3];
arr = {34,55,434}; //错误1:动态初始化不能通过静态初始化赋值
//错误2
int[] nums = new int[5]{1,2,3,4,5}; 
//正确
int arr[] = new int[3];
arr[0]=1;
arr[1]=2;
arr[3]=5;

4)什么时候使用静态初始化,什么时候使用初始化?

  • 当我们事前知道,需要存储哪些数据时候,选用静态初始化。
  • 当我们实现不知道,需要存储哪些数据时候,只能使用动态初始化。

5)修改数组元素:

数组钉以后,首先需要初始化,然后才能使用。无论是静态、动态初始化,初始化后都可以通过下表来修改元素;此外,同类型的数组变量可以相互赋值(改变引用地址)。见上例。

int[] a = new int[]{1, 2, 3}; //静态初始化
a[0] = 9; //通过下标修改数组元素
System.out.println(Arrays.toString(a)); //[0, 2, 3]

int[] b = new int[6]; //动态初始化
b[1] = 0;
System.out.println(Arrays.toString(b)); //[0, 1, 0, 0, 0, 0]

b = a; //同类型的数组变量可以赋值(改变引用地址)
System.out.println(Arrays.toString(b)); //[0, 2, 3]
1.3)其他:

1)数组动态添加元素:

数组是不能添加元素的,因为他们在初始化时就已定好长度了,不能改变长度。可以通过如下方式来实现:

方法一:Arrays.copyOf:

int[] array1 = new int[]{1,2,3};
int[] newArray = Arrays.copyOf(array1, array1.length + 1);
System.out.println(Arrays.toString(newArray)); //[1,2,3,0]
newArray[newArray.length-1] = 4;
System.out.println(Arrays.toString(newArray)); //[1,2,3,4]

方法二:数组转成list:

将数组转成List,但是要注意,asList方法返回的是一个视图,不能在其基础上进行操作,例如:

Integer[] array2 = new Integer[]{1,2,3};
List<Integer> asList = Arrays.asList(array2); 
asList.add(4);//Exception in thread "main" java.lang.UnsupportedOperationException

正确做法:

Integer[] array2 = new Integer[]{1,2,3};
List<Integer> asList = Arrays.asList(array2); 
List<Integer> tmpList = new ArrayList<>(asList);
tmpList.add(4);
System.out.println(tmpList); //[1,2,3,4]

2)list转数组:

最简单的方法是可以通过循环。这里介绍其他的方法:

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
String[] array = list.toArray(new String[list.size()]);
System.out.println(Arrays.toString(array)); //["a", "b"]

 2、二维数组

2.1)二维数组声明、初始化:

1)二维数组的定义:

数组类型[][] 数组名;

二维数组的初始化同上,分为静态和动态初始化。例如:

int a[][]={{1,2,3},{4,5,6}}; //简易的静态初始化
//动态初始化
int[][] b = new int[4][2];
System.out.println(Arrays.toString(b)); //[[0, 0], [0, 0], [0, 0], [0, 0]]
//接下来可以通过小标赋值

需要注意的是,二维数组中每个元素又是一个一维数组,每个一维数组的长度可以不一样。所以,可以定义成一个不定长二维数组。类似:[[1],[1,2,3],[4,5]] 。在动态声明初始化时,可以不用指定第二位大小!

int[][] aa = new int[3][]; //第二维的长度可以动态申请
aa[0] = new int[1];
aa[1] = new int[]{1, 2};
aa[2] = new int[]{3,4,5};
a[0][0] = 0;
或者
int[][] bb = new int[][]{{0}, {1,2}, {3,4,5}};

//当不指定二维下标时,打印如下
int[][] cc = new int[2][];
System.out.println(Arrays.toString(b)); //[null, null]

2)修改二维数组的元素:

二维数组是一个数组的数组,所以可以通过两个下标来修改具体的数组元素,也可以通过一个下标来修改一维数组的引用。

int[][] aa = {{1,2,3}, {4,5}, {6}};
System.out.println(Arrays.deepToString(aa)); 

int[] a = {1, 2, 3};
int[] b = new int[6];
b[2] = 99;

int[][] bb = new int[2][3];
bb[0] = a;
bb[1] = new int[]{4,5,6};
System.out.println("before:" + Arrays.deepToString(bb)); //[[1, 2, 3], [4, 5, 6]]
bb[0] = b; //修改一维数组的引用
bb[1][0] = 99;
System.out.println("after:" + Arrays.deepToString(bb)); //[[0, 0, 99, 0, 0, 0], [99, 5, 6]]

int[][] cc = new int[2][3];
cc[0][3] = 1; //java.lang.ArrayIndexOutOfBoundsException: 3

说明:bb采用动态初始化方式定义了一个2*3的数组,但是可以通过修改一维数组的下标引用,讲其第一个元素改成6维的数组(第12行)。

https://blog.csdn.net/liuxiao723846/article/details/100990110

2.2)其他:

1)数组的toString:

打印数组可以使用Arrays.toString()或Arrays.deepToString();方法,后者可以打印二维数组。

int[] a = {1, 2, 3};
System.out.println(a); //[I@71dac704
System.out.println(Arrays.toString(a)); //[1, 2, 3]
//二维数组
int[][] aa = {{1,2,3}, {4,5}, {6}};
System.out.println(Arrays.deepToString(aa)); //[[1, 2, 3], [4, 5], [6]]

2)list转成二维数组:

首先我们试着使用list转一维数组的方式

List<List<Float>> list1 = new ArrayList<>();

List<Float> list1_1 = new ArrayList<>();
list1_1.add(1.0f);
list1_1.add(1.1f);
list1_1.add(1.2f);
List<Float> list1_2 = new ArrayList<>();
list1_2.add(2.0f);
list1_2.add(2.1f);
list1_2.add(2.2f);

list1.add(list1_1);
list1.add(list1_2);

System.out.println("list1:" + list1); //list1:[[1.0, 1.1, 1.2], [2.0, 2.1, 2.2]]
Float[][] array = list1.toArray(new Float[2][3]); //Exception in thread "main" java.lang.ArrayStoreException

接下来使用java8 Steam api:

Float[][] array = list1.stream()
  .map(l -> l.toArray(new Float[l.size()])) //l的类型是List<Float>
  .toArray(Float[][]::new);
System.out.println(Arrays.deepToString(array));
//对于List<List<String>>
List<List<String>> list = Arrays.asList(
        Arrays.asList("A", "B", "C"),
        Arrays.asList("B", "D"),
        Arrays.asList("E", "F")
);
String[][] arr = list.stream()
        .map(l -> l.stream().toArray(String[]::new))
        .toArray(String[][]::new);
System.out.println(Arrays.deepToString(arr));

//对于List<List<Integer>>
List<List<Integer>> list = Arrays.asList(
        Arrays.asList(1, 3, 2),
        Arrays.asList(1, 2, 2),
        Arrays.asList(1, 2)
);
int[][] arr = list.stream()
        .map(l -> l.stream().mapToInt(Integer::intValue).toArray())
        .toArray(int[][]::new);
System.out.println(Arrays.deepToString(arr));
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赶路人儿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值