이 기사의 편집자는 JAVA 배열의 사용에 대해 소개할 것입니다. 필요한 친구는 이를 참고할 수 있습니다.
JAVA 배열과 컨테이너 클래스의 세 가지 주요 차이점은 효율성, 유형입니다. 그리고 기본 유형을 저장하는 기능. JAVA에서 배열은 일련의 객체 참조를 저장하고 무작위로 액세스하는 가장 효율적인 방법입니다. 배열은 요소 액세스를 매우 빠르게 만드는 간단한 선형 시퀀스입니다. 그러나 이를 위해 지불되는 대가는 배열의 크기가 고정되어 있으며 수명 동안 변경할 수 없다는 것입니다.
제네릭 및 자동 패키징 메커니즘의 출현 덕분에 컨테이너는 이제 배열만큼 쉽게 기본 유형과 함께 사용할 수 있습니다. 배열과 컨테이너 모두 어느 정도 남용을 방지할 수 있습니다. 범위를 벗어나면 RuntimeException이 발생합니다. 배열의 유일한 장점은 효율성입니다. 그러나 보다 일반적인 문제를 해결하려는 경우 배열이 너무 제한적일 수 있으므로 이 경우에도 대부분의 사람들은 컨테이너를 선택합니다.
따라서 최신 JAVA 버전을 사용하는 경우 배열보다 컨테이너를 선호해야 합니다. 성능이 문제인 것으로 입증되고 어레이로 전환하면 성능이 향상되는 경우에만 프로그램을 어레이로 리팩터링해야 합니다.
[초기화]
JAVA는 배열 초기화에 대해 매우 엄격한 규정을 두고 있어 배열 남용을 효과적으로 방지할 수 있습니다. 초기화 오류가 발생하면 RuntimeException 대신 CompileException이 직접 발생합니다. 배열이 적절하게 초기화될 때까지 이 배열 참조로 아무 작업도 수행할 수 없습니다.
배열 정의에는 int[] 배열과 int 배열[]이 포함됩니다. 일반적으로 첫 번째 스타일은 변수 이름과 유형을 구분하는 데 사용됩니다.
배열을 초기화하는 방법에는 정적 초기화와 동적 초기화의 두 가지가 있습니다. 길이는 초기화 시 지정해야 하며, 다차원 배열의 첫 번째 차원의 길이를 명시해야 하며, 높은 차원부터 낮은 차원까지 정의해야 합니다. 초기화 작업은 코드 어디에나 있을 수 있지만, {} 메서드는 배열이 생성된 위치에만 나타날 수 있습니다. 구체적인 초기화 방법은 프로그램을 참조하세요.
코드는 다음과 같습니다.
public class javaArrayInit{ public static void main(String args[]){ int[] arrayA; //未初始化 int[] arrayB = new int[5]; //静态初始化 //System.out.println(arrayA.length); //CompileException System.out.println("arrayB length: " + arrayB.length); //无法得到实际保存的元素个数 arrayA = new int[10]; //动态初始化 System.out.println("arrayA length: " + arrayA.length); int[] arrayC = new int[]{1,2,3,4}; System.out.println("arrayC length: " + arrayC.length); //int[] arrayD = new int[1]{1}; //错误的初始化,不能同时定义维和初始化值 int[][] arrayE = new int[1][]; System.out.println("arrayE length: " + arrayE.length); //int[][] arrayF = new int[][2]; //应先指定高维的长度 int[][] arrayG = new int[][]{{1,2,3,4},{5,6,7},{7,24,23,24}}; System.out.println("arrayG length: " + arrayG.length); int[][][] arrayH = new int[][][]{{{1,2,3},{4,5,6},{7,8,9},{10,11,12}}}; System.out.println("arrayH length: " + arrayH.length); dummyArray[] arrayI = {new dummyArray(),new dummyArray()}; //自定义数组类型 System.out.println("arrayI length: " + arrayI.length); System.out.println("arrayI[1]: " + arrayI[1].getValue()); dummyArray[] arrayK = new dummyArray[5]; System.out.println("arrayK[0]: " + arrayK[0]); //null for(int i = 0; i < arrayK.length; i++){ arrayK[i] = new dummyArray(); } System.out.println("arrayK[0]: " + arrayK[0].getValue()); //2 } } class dummyArray{ private static int temp; private final int arrayValue = temp++; public int getValue(){ return arrayValue; } }
출력:
arrayB length: 5 arrayA length: 10 arrayC length: 4 arrayE length: 1 arrayG length: 3 arrayH length: 1 arrayI length: 2 arrayI[1]: 1 arrayK[0]: null arrayK[0]: 2
[length]
읽기 전용 멤버 길이는 배열 객체의 일부입니다(이 변수는 실제로 API에서 선언되지 않고 런타임 시 동적으로 생성되지만). 이는 액세스할 수 있는 유일한 필드 또는 메서드입니다. [] 구문은 배열 객체에 액세스하는 유일한 방법이며 컨테이너는 get() 메서드를 통해 액세스됩니다. Array.length를 사용하여 배열의 크기를 가져올 수 있습니다. String 유형의 String.length()와는 다릅니다. Array는 멤버 변수를 사용하고 String은 멤버 메서드를 사용합니다. 동시에 Array.length는 배열의 크기만 가져올 수 있지만 배열에 실제로 포함된 요소 수는 알 수 없습니다. 다차원 배열의 길이는 첫 번째 차원의 길이만 계산합니다.
코드는 다음과 같습니다:
public class javaArrayLength{ public static void main(String args[]){ int[] arrayA = new int[15]; arrayA[1] = 1; arrayA[2] = 2; arrayA[3] = 3; System.out.println("arrayA length: " + arrayA.length); int[][] arrayB = new int[10][]; System.out.println("arrayB length: " + arrayB.length); int[][] arrayC = new int[][]{{1,1,1,2,},{1,1,2,3,4,5},{4,5,6,7,7},};//注意后面的逗号 System.out.println("arrayC length: " + arrayC.length); int[][] arrayD = new int[][]{{1,1,1,2,},{1,1,2,3,4,5},{4,5,6,7,7},{}}; System.out.println("arrayD length: " + arrayD.length); } }
출력:
arrayA length: 15 arrayB length: 10 arrayC length: 3 arrayD length: 4
[Arrays.fill]
Arrays.fill은 매우 효과가 제한적입니다. 각 위치를 동일한 값으로만 채울 수 있기 때문입니다(객체의 경우 동일한 참조가 복사되어 채워집니다). Arrays.fill을 사용하면 배열 전체를 채울 수도 있고, 배열의 특정 영역을 채울 수도 있지만, Arrays.fill은 단일 값으로만 호출할 수 있기 때문에 그다지 유용하지는 않습니다.
[할당 및 참조]
JAVA 배열이 초기화되면 배열에 대한 참조만 있고 배열에 저장 공간을 할당하지 않습니다. 따라서 배열 간 복사는 동일한 객체가 동작하기 때문에 단순히 "=" 할당을 사용할 수 없습니다. 다음 프로그램:
코드는 다음과 같습니다:
public class javaArrayQuote{ public static void main(String args[]){ String testA = "testA"; String testB = "testB"; String[] arrayA = new String[]{"arrayA"}; String[] arrayB = new String[]{"arrayB"}; testB = testA; testB = "testB change"; System.out.println("I'm testA,I have no changed: " + testA); arrayB = arrayA; arrayB[0] = "arrayB have changed"; System.out.println("I'm arrayA, I have no changed: " + arrayA[0]); } }
출력:
저는 testA입니다. 변경된 사항이 없습니다: testA
저는 arrayA입니다. 변경된 사항이 없습니다. arrayB가 변경되었습니다
可以看出,我们改变arrayB[0]的值,改变的是引用的数组,因此我们输出arrayA[0],其实和arrayB[0]一样。
【数组复制】
JAVA中复制数组的方法:
1.使用FOR循环复制全部或指定元素,效率较低
2.使用clone方法,得到数组的值,而不是引用。然而clone不能复制指定元素,灵活性较低
3.使用System.arraycopy(src, srcPos, dest, destPos, length)方法,java标准类库提供有static方法 System.arraycopy(),用它复制数组要比for循环快很多,System.arraycopy()针对所有类型做了重载,基本类型数组和对象数组都可以用System.arraycopy()复制,但是对象数组只是复制引用,不会出现两份对象的拷贝。这被称作浅复制(shallowcopy)。
src:源数组;
srcPos:源数组要复制的起始位置;
dest:目的数组;
destPos:目的数组放置的起始位置;
length:复制的长度.
注意:System.arraycopy()不会进行自动包装和自动拆包,因此两个数组必须是同类型或者可以转换为同类型的数组。同时,这个方法也可以用于复制数组本身。
int[] test ={0,1,2,3,4,5,6};
System.arraycopy(test,0,test,3,3);
则结果为:{0,1,2,0,1,2,6};
测试程序如下:
代码如下:
public class javaArrayCopy{ public static void main(String args[]){ int[] array = {1,2,3,4,5,6,7,8,9}; //for循环方法 int[] arrayA = new int[9]; for(int i = 0; i < arrayA.length; i++){ arrayA[i] = array[i]; System.out.print(arrayA[i] + ","); } //测试 System.out.println(""); arrayA[1] = 19; for(int i = 0; i < arrayA.length; i++){ System.out.print(arrayA[i] + ","); } System.out.println(""); for(int i = 0; i < array.length; i++){ System.out.print(array[i] + ","); } System.out.println(""); //clone方法 int[] arrayB = new int[9]; arrayB = array.clone(); //测试 arrayB[1] = 19; for(int i = 0; i < arrayB.length; i++){ System.out.print(arrayB[i] + ","); } System.out.println(""); for(int i = 0; i < array.length; i++){ System.out.print(array[i] + ","); } System.out.println(""); //System.arrayCopy 方法 int[] arrayC = new int[9]; System.arraycopy(array, 0, arrayC, 0, arrayC.length); //测试 arrayC[1] = 19; for(int i = 0; i < arrayC.length; i++){ System.out.print(arrayC[i] + ","); } System.out.println(""); for(int i = 0; i < array.length; i++){ System.out.print(array[i] + ","); } } }
【数组比较】
Arrays提供了重载后的equals()方法,针对所有类型和Object类型都做了重载,用来比较整个数组。数组相等的条件是元素个数必须相等,并且对应位置的元素也相等。而多维数组的比较用deepEquals()方法。Array.equals()方法比较的两个数组必须是同类型的数组。
代码如下:
import java.util.Arrays; public class javaArrayEquals{ public static void main(String args[]){ int[] arrayA = {1,2,3}; int[] arrayB = {1,2,3,}; int[] arrayC = new int[4]; //if int[] arrayC = new int[3],return true arrayC[0] = 1; arrayC[1] = 2; arrayC[2] = 3; System.out.println(Arrays.equals(arrayA, arrayB)); System.out.println(Arrays.equals(arrayA, arrayC)); String[][] arrayD = {{"a","b"},{"c","d"}}; String[][] arrayE = {{"a","b"},{"c","d"}}; System.out.println(Arrays.deepEquals(arrayD, arrayE)); } }
【数组排序与查找】
数组提供了内置的排序方法sort(),可以对任意基本类型数组或者对象数组进行排序(该对象必须实现Comparable接口或者具有相关联的Comparator)。JAVA对不同的类型提供了不同的排序方法----针对基本类型设计的快速排序,以及针对对象设计的“稳定归并排序”,所以无需担心数组排序的效率问题。
binarySearch()用于在以排好序的数组中快速查找元素,如果对未排序的数组使用binarySearch(),那么将产生难以预料的结果。
【返回数组】
C和C++不能返回一个数组,只能返回指向数组的指针,因为返回数组使得控制数组的生命周期变得困难,并且容易造成内存泄漏。java允许直接返回一个数组,并且可以由垃圾回收机制回收。
【数组与容器转换】【无法转换基本类型数组】
数组转为List:
代码如下:
import java.util.*; public class arrayToList{ public static void main(String args[]){ String[] arrayA = {"a","b","c"}; List listA = java.util.Arrays.asList(arrayA); System.out.println("listA: " + listA); int[] arrayB = {1,2,3}; List listB = java.util.Arrays.asList(arrayB); System.out.println("listB: " + listB); Integer[] arrayC = {1,2,3}; List listC = java.util.Arrays.asList(arrayC); System.out.println("listC: " + listC); } }
输出:
listA: [a, b, c] listB: [[I@de6ced] listC: [1, 2, 3]
为什么int和Integer输出会不同呢?
List转为数组
代码如下:
import java.util.*; public class listToArray{ public static void main(String args[]){ List<String> list = new ArrayList<String>(); String[] array; list.add("testA"); list.add("testB"); list.add("testC"); System.out.println("list: " + list); String[] strings = new String[list.size()]; array = list.toArray(strings); for(int i = 0, j = array.length; i < j; i++){ System.out.print(array[i] + ","); } } }
输出为:
list: [testA, testB, testC]
testA,testB,testC
【去除重复数据】
利用数组和容器转换可以方便地去除数组重复数据,不过如果数组过大,效率是一个问题。
代码如下:
import java.util.*; public class javaArrayUnique{ public static void main(String args[]){ String[] array = {"a","b","a","a","c","b"}; arrayUnique(array); //test for(int i = 0, j = arrayUnique(array).length; i < j; i++){ System.out.print(arrayUnique(array)[i] + ","); } } public static String[] arrayUnique(String[] array){ List<String> list = new ArrayList<String>(); for(int i = 0, j = array.length; i < j; i++){ if(!list.contains(array[i])){ list.add(array[i]); } } String[] strings = new String[list.size()]; String[] arrayUnique = list.toArray(strings); return arrayUnique; } }
关于效率问题,我做了一个对比,在我电脑上运行十万数据的数组大概是577ms,而运行一百万数据的数据大约要5663ms。这还跟计算机的运行能力有关,但是明显是随着数组大小递增的。
代码如下:
import java.util.*; public class javaArrayUnique{ public static void main(String args[]){ Double[] array = new Double[100000]; for(int i = 0, j = array.length; i < j; i++){ array[i] = Math.ceil(Math.random()*1000); } Double[] arrayB = new Double[1000000]; for(int i = 0, j = arrayB.length; i < j; i++){ arrayB[i] = Math.ceil(Math.random()*1000); } System.out.println("start"); long startTime = System.currentTimeMillis(); arrayUnique(array); long endTime = System.currentTimeMillis(); System.out.println("array unique run time: " +(endTime - startTime) +"ms"); long startTimeB = System.currentTimeMillis(); arrayUnique(arrayB); long endTimeB = System.currentTimeMillis(); System.out.println("arrayB unique run time: " +(endTimeB - startTimeB) +"ms"); } public static Double[] arrayUnique(Double[] array){ List<Double> list = new ArrayList<Double>(); for(int i = 0, j = array.length; i < j; i++){ if(!list.contains(array[i])){ list.add(array[i]); } } Double[] doubles = new Double[list.size()]; Double[] arrayUnique = list.toArray(doubles); return arrayUnique; } }
输出:
startarray unique run time: 577msarrayB unique run time: 5663ms
위 내용은 JAVA 배열 사용 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!