Java에서 현재 요소를 유지하면서 배열 크기를 조정합니까?
Java에서 배열 크기를 조정하는 방법을 찾았지만 현재 요소를 유지하면서 배열 크기를 조정하는 방법을 찾을 수 없습니다 .
같은 예제 코드를 찾았 int[] newImage = new int[newWidth];
지만 이전에 저장된 요소를 삭제합니다.
내 코드는 기본적으로 이렇게 할 것입니다. 새 요소가 추가 될 때마다 배열이 1 만큼 커집니다 . 동적 프로그래밍으로이 작업을 수행 할 수 있다고 생각하지만 구현 방법을 잘 모르겠습니다.
Java에서는 배열의 크기를 조정할 수 없습니다. 다음 중 하나가 필요합니다.
원하는 크기의 새 배열을 만들고 다음을 사용하여 원래 배열의 내용을 새 배열로 복사합니다.
java.lang.System.arraycopy(...);
java.util.ArrayList<T>
배열을 더 크게 만들어야 할 때이 작업을 수행 하는 클래스를 사용하십시오 . 질문에서 설명하는 내용을 멋지게 요약합니다.java.util.Arrays.copyOf(...)
원래 배열의 내용으로 더 큰 배열을 반환하는 메서드를 사용하십시오 .
좋지는 않지만 작동합니다.
int[] a = {1, 2, 3};
// make a one bigger
a = Arrays.copyOf(a, a.length + 1);
for (int i : a)
System.out.println(i);
앞서 언급했듯이 ArrayList 로 이동하십시오.
여기에 몇 가지 방법이 있습니다.
방법 1 : System.arraycopy()
:
지정된 위치에서 시작하여 지정된 소스 배열의 배열을 대상 배열의 지정된 위치로 복사합니다. 배열 구성 요소의 하위 시퀀스는 src에서 참조하는 소스 배열에서 dest에서 참조하는 대상 배열로 복사됩니다. 복사 된 구성 요소의 수는 길이 인수와 같습니다. 소스 배열의 srcPos ~ srcPos + length-1 위치의 구성 요소는 대상 배열의 destPos ~ destPos + length-1 위치에 각각 복사됩니다.
Object[] originalArray = new Object[5];
Object[] largerArray = new Object[10];
System.arraycopy(originalArray, 0, largerArray, 0, originalArray.length);
방법 2 : Arrays.copyOf()
:
지정된 배열을 복사하고 필요한 경우 널 (NULL)로 자르거나 패딩하여 복사본이 지정된 길이를 갖도록합니다. 원본 배열과 복사본 모두에서 유효한 모든 인덱스의 경우 두 배열에 동일한 값이 포함됩니다. 복사본에서는 유효하지만 원본이 아닌 인덱스의 경우 복사본에는 null이 포함됩니다. 이러한 인덱스는 지정된 길이가 원래 배열의 길이보다 큰 경우에만 존재합니다. 결과 배열은 원래 배열과 정확히 동일한 클래스입니다.
Object[] originalArray = new Object[5];
Object[] largerArray = Arrays.copyOf(originalArray, 10);
이 방법은 일반적으로 System.arraycopy()
배후에서 사용합니다 .
방법 3 : ArrayList
:
List 인터페이스의 크기 조정 가능 배열 구현. 모든 선택적 목록 작업을 구현하고 null을 포함한 모든 요소를 허용합니다. List 인터페이스를 구현하는 것 외에도이 클래스는 목록을 저장하기 위해 내부적으로 사용되는 배열의 크기를 조작하는 메서드를 제공합니다. (이 클래스는 비 동기화된다는 점을 제외하면 Vector와 거의 동일합니다.)
ArrayList는 포함 할 수있는 것보다 더 많은 요소를 추가하면 자동으로 확장된다는 점을 제외하면 배열과 유사하게 작동합니다. 그것은 것 배열에 연동 하고, 용도는 Arrays.copyOf .
ArrayList<Object> list = new ArrayList<>();
// This will add the element, resizing the ArrayList if necessary.
list.add(new Object());
당신은 당신을 ArrayList
위해 일하는 것을 사용할 수 있습니다.
배열 대신 ArrayList를 사용할 수 있습니다. n 개의 요소를 추가 할 수 있도록
List<Integer> myVar = new ArrayList<Integer>();
표준 클래스 java.util.ArrayList는 크기 조정이 가능한 배열이며 새 요소가 추가되면 커집니다.
어레이 크기는 변경할 수 없습니다. 그러나 더 큰 배열을 만들어 한 배열의 요소를 다른 배열로 복사 할 수 있습니다.
Array가 가득 찬 경우 두 배 크기의 Array를 만들고 Array가 절반이 찬 경우 Array를 절반으로 줄이는 것이 좋습니다.
public class ResizingArrayStack1 {
private String[] s;
private int size = 0;
private int index = 0;
public void ResizingArrayStack1(int size) {
this.size = size;
s = new String[size];
}
public void push(String element) {
if (index == s.length) {
resize(2 * s.length);
}
s[index] = element;
index++;
}
private void resize(int capacity) {
String[] copy = new String[capacity];
for (int i = 0; i < s.length; i++) {
copy[i] = s[i];
s = copy;
}
}
public static void main(String[] args) {
ResizingArrayStack1 rs = new ResizingArrayStack1();
rs.push("a");
rs.push("b");
rs.push("c");
rs.push("d");
}
}
배열의 크기를 조정할 수는 없지만 이전 값을 유지하거나 java.util.List를 사용하여 재정의 할 수 있습니다.
다음은 두 가지 솔루션을 따르지만 아래 코드를 실행하는 성능 차이를 포착하십시오.
자바 목록은 450 배 빠르지 만 메모리는 20 배 더 무겁습니다!
testAddByteToArray1 nanoAvg : 970355051 memAvg : 100000 testAddByteToList1 nanoAvg : 1923106 memAvg : 2026856 testAddByteToArray1 nanoAvg : 919582271 memAvg : 100000 testAddByteToList1 nanoAvg : 1922660 memAvg : 2026856 testAddByteToArray1 nanoAvg : 917727475 memAvg : 100000 testAddByteToList1 nanoAvg : 1904896 memAvg : 2026856 testAddByteToArray1 nanoAvg : 918483397 memAvg : 100000 testAddByteToList1 nanoAvg : 1907243 memAvg : 2026856
import java.util.ArrayList;
import java.util.List;
public class Test {
public static byte[] byteArray = new byte[0];
public static List<Byte> byteList = new ArrayList<>();
public static List<Double> nanoAvg = new ArrayList<>();
public static List<Double> memAvg = new ArrayList<>();
public static void addByteToArray1() {
// >>> SOLUTION ONE <<<
byte[] a = new byte[byteArray.length + 1];
System.arraycopy(byteArray, 0, a, 0, byteArray.length);
byteArray = a;
//byteArray = Arrays.copyOf(byteArray, byteArray.length + 1); // the same as System.arraycopy()
}
public static void addByteToList1() {
// >>> SOLUTION TWO <<<
byteList.add(new Byte((byte) 0));
}
public static void testAddByteToList1() throws InterruptedException {
System.gc();
long m1 = getMemory();
long n1 = System.nanoTime();
for (int i = 0; i < 100000; i++) {
addByteToList1();
}
long n2 = System.nanoTime();
System.gc();
long m2 = getMemory();
byteList = new ArrayList<>();
nanoAvg.add(new Double(n2 - n1));
memAvg.add(new Double(m2 - m1));
}
public static void testAddByteToArray1() throws InterruptedException {
System.gc();
long m1 = getMemory();
long n1 = System.nanoTime();
for (int i = 0; i < 100000; i++) {
addByteToArray1();
}
long n2 = System.nanoTime();
System.gc();
long m2 = getMemory();
byteArray = new byte[0];
nanoAvg.add(new Double(n2 - n1));
memAvg.add(new Double(m2 - m1));
}
public static void resetMem() {
nanoAvg = new ArrayList<>();
memAvg = new ArrayList<>();
}
public static Double getAvg(List<Double> dl) {
double max = Collections.max(dl);
double min = Collections.min(dl);
double avg = 0;
boolean found = false;
for (Double aDouble : dl) {
if (aDouble < max && aDouble > min) {
if (avg == 0) {
avg = aDouble;
} else {
avg = (avg + aDouble) / 2d;
}
found = true;
}
}
if (!found) {
return getPopularElement(dl);
}
return avg;
}
public static double getPopularElement(List<Double> a) {
int count = 1, tempCount;
double popular = a.get(0);
double temp = 0;
for (int i = 0; i < (a.size() - 1); i++) {
temp = a.get(i);
tempCount = 0;
for (int j = 1; j < a.size(); j++) {
if (temp == a.get(j))
tempCount++;
}
if (tempCount > count) {
popular = temp;
count = tempCount;
}
}
return popular;
}
public static void testCompare() throws InterruptedException {
for (int j = 0; j < 4; j++) {
for (int i = 0; i < 20; i++) {
testAddByteToArray1();
}
System.out.println("testAddByteToArray1\tnanoAvg:" + getAvg(nanoAvg).longValue() + "\tmemAvg:" + getAvg(memAvg).longValue());
resetMem();
for (int i = 0; i < 20; i++) {
testAddByteToList1();
}
System.out.println("testAddByteToList1\tnanoAvg:" + getAvg(nanoAvg).longValue() + "\t\tmemAvg:" + getAvg(memAvg).longValue());
resetMem();
}
}
private static long getMemory() {
Runtime runtime = Runtime.getRuntime();
return runtime.totalMemory() - runtime.freeMemory();
}
public static void main(String[] args) throws InterruptedException {
testCompare();
}
}
배열의 크기를 조정할 수 없습니다. 그러나 원래 배열을 새로 크기가 지정된 배열로 복사하고 현재 요소를 유지하여 배열의 크기를 변경할 수 있습니다. 요소를 제거하고 크기를 조정하여 배열의 크기를 줄일 수도 있습니다.
import java.util.Arrays
public class ResizingArray {
public static void main(String[] args) {
String[] stringArray = new String[2] //A string array with 2 strings
stringArray[0] = "string1";
stringArray[1] = "string2";
// increase size and add string to array by copying to a temporary array
String[] tempStringArray = Arrays.copyOf(stringArray, stringArray.length + 1);
// Add in the new string
tempStringArray[2] = "string3";
// Copy temp array to original array
stringArray = tempStringArray;
// decrease size by removing certain string from array (string1 for example)
for(int i = 0; i < stringArray.length; i++) {
if(stringArray[i] == string1) {
stringArray[i] = stringArray[stringArray.length - 1];
// This replaces the string to be removed with the last string in the array
// When the array is resized by -1, The last string is removed
// Which is why we copied the last string to the position of the string we wanted to remove
String[] tempStringArray2 = Arrays.copyOf(arrayString, arrayString.length - 1);
// Set the original array to the new array
stringArray = tempStringArray2;
}
}
}
}
일부 클래스 내에서 아래 솔루션을 시도해 볼 수 있습니다.
int[] a = {10, 20, 30, 40, 50, 61};
// private visibility - or change it as needed
private void resizeArray(int newLength) {
a = Arrays.copyOf(a, a.length + newLength);
System.out.println("New length: " + a.length);
}
죄송합니다. 현재로서는 배열 크기를 조정할 수 없으며 절대 없을 수도 있습니다.
그래서 제 권장 사항 은 프로세스의 시작부터 필요한 배열의 크기를 얻을 수있는 솔루션을 찾기 위해 더 많이 생각 하는 것입니다. 이것은 종종 코드를 실행하는 데 조금 더 많은 시간 (라인)이 필요하지만 많은 메모리 리소스를 절약 할 수 있음을 의미합니다.
ReferenceURL : https://stackoverflow.com/questions/13197702/resize-an-array-while-keeping-current-elements-in-java
'IT TIP' 카테고리의 다른 글
Android 기기의 CURRENT 방향 (ActivityInfo.SCREEN_ORIENTATION_ *)은 어떻게 얻습니까? (0) | 2020.12.28 |
---|---|
UIImagePickerController로 만든 동영상의 파일 크기를 줄이려면 어떻게해야합니까? (0) | 2020.12.28 |
Django Rest Framework로 여러 모델 인스턴스를 생성하려면 어떻게해야합니까? (0) | 2020.12.28 |
C #의 날짜 시간 추가 일 (0) | 2020.12.28 |
빈 문자열이있는 SQL Coalesce (0) | 2020.12.28 |