Java의 불변 배열
Java의 원시 어레이에 대한 불변의 대안이 있습니까?원시 배열 만들기final
그런 걸 하는 걸 막지는 않아요
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
배열의 요소를 변경하지 않았으면 합니다.
원시 어레이에서는 안 돼요목록 또는 기타 데이터 구조를 사용해야 합니다.
List<Integer> items = Collections.unmodifiableList(Arrays.asList(0,1,2,3));
어레이 또는 어레이를 사용하지 않는 것이 좋습니다.unmodifiableList
이 목적을 위해 존재하는 Guava의 Unmutable List를 사용합니다.
ImmutableList<Integer> values = ImmutableList.of(0, 1, 2, 3);
다른 사람들이 지적했듯이 Java에서는 불변 어레이를 사용할 수 없습니다.
원래 어레이에 영향을 주지 않는 어레이를 반환하는 방법이 절대적으로 필요한 경우 매번 어레이를 복제해야 합니다.
public int[] getFooArray() {
return fooArray == null ? null : fooArray.clone();
}
확실히 이것은 꽤 비싸지만(getter를 호출할 때마다 풀 카피를 작성하기 때문에), 인터페이스를 변경할 수 없는 경우(사용하기 위해)List
고객이 사내를 변경할 위험을 감수할 수 없습니다.필요할 수도 있습니다.
이 기술을 방어적 복사라고 합니다.
Java에서 불변의 배열을 만드는 방법은 다음과 같습니다.
final String[] IMMUTABLE = new String[0];
요소가 0인 어레이는(분명히) 변환할 수 없습니다.
이 기능은, 유저에게 있어서,List.toArray
변환 방법List
배열로 이동합니다.빈 어레이도 메모리를 차지하기 때문에 빈 어레이를 계속 생성하여 항상 이 어레이를 에 전달함으로써 메모리 할당을 절약할 수 있습니다.toArray
방법.이 메서드는 전달한 어레이에 충분한 공간이 없는 경우 새 어레이를 할당하지만 전달한 어레이가 반환되므로(리스트가 비어 있음) 언제든지 해당 어레이를 재사용할 수 있습니다.toArray
공중에List
.
final static String[] EMPTY_STRING_ARRAY = new String[0];
List<String> emptyList = new ArrayList<String>();
return emptyList.toArray(EMPTY_STRING_ARRAY); // returns EMPTY_STRING_ARRAY
Java 9부터는List.of(...)
, JavaDoc.
이 메서드는 불변의 값을 반환합니다.List
매우 효율적입니다.
또 하나의 답변
static class ImmutableArray<T> {
private final T[] array;
private ImmutableArray(T[] a){
array = Arrays.copyOf(a, a.length);
}
public static <T> ImmutableArray<T> from(T[] a){
return new ImmutableArray<T>(a);
}
public T get(int index){
return array[index];
}
}
{
final ImmutableArray<String> sample = ImmutableArray.from(new String[]{"a", "b", "c"});
}
Guava 22 이후, 패키지에서com.google.common.primitives
3개의 새로운 클래스를 사용할 수 있습니다.이러한 클래스에서는,ImmutableList
.
그들은 또한 건축업자를 가지고 있다.예:
int size = 2;
ImmutableLongArray longArray = ImmutableLongArray.builder(size)
.add(1L)
.add(2L)
.build();
또는 컴파일 시 크기를 알고 있는 경우:
ImmutableLongArray longArray = ImmutableLongArray.of(1L, 2L);
이는 Java 프리미티브용 어레이의 불변의 뷰를 얻는 또 다른 방법입니다.
(퍼포먼스상의 이유 또는 메모리 절약을 위해) 'java.lang'이 아닌 네이티브 'int'가 필요한 경우.Integer'를 선택하면 래퍼 클래스를 직접 작성해야 합니다.인터넷에는 다양한 IntArray 구현이 있지만 Koders IntArray, Lucene IntArray는 불변의 것이 없었습니다.아마 다른 사람들도 있을 거예요.
Java9의 of(E... elements) 메서드를 사용하여 다음 행만 사용하여 불변 목록을 작성할 수 있습니다.
List<Integer> items = List.of(1,2,3,4,5);
위의 메서드는 임의의 수의 요소를 포함하는 불변의 목록을 반환합니다. 이 의 정수를 하면 " "가 .java.lang.UnsupportedOperationException
.이 메서드는 단일 배열을 인수로 받아들이기도 합니다.
String[] array = ... ;
List<String[]> list = List.<String[]>of(array);
아니, 이건 불가능해.그러나 다음과 같은 작업을 수행할 수 있습니다.
List<Integer> temp = new ArrayList<Integer>();
temp.add(Integer.valueOf(0));
temp.add(Integer.valueOf(2));
temp.add(Integer.valueOf(3));
temp.add(Integer.valueOf(4));
List<Integer> immutable = Collections.unmodifiableList(temp);
여기에는 래퍼를 사용해야 하며 배열이 아닌 목록이지만 가장 가까운 목록입니다.
라이브러리에서 이더 수 : Google Guava 라음 。List<Integer> Ints.asList(int... backingArray)
예:
List<Integer> x1 = Ints.asList(0, 1, 2, 3)
List<Integer> x1 = Ints.asList(new int[] { 0, 1, 2, 3})
불변성과 복싱을 모두 피하고 싶다면 박스에서 벗어날 방법이 없다.그러나 기본 배열을 내부에 유지하고 메서드를 통해 요소에 대한 읽기 전용 액세스를 제공하는 클래스를 만들 수 있습니다.
while while while while while while while while whileCollections.unmodifiableList()
어레이를가 이미 되어 있는 수 를 들어, 「」, 「」, 「」등).String[]
이러한 분해를 방지하기 위해 값을 저장하는 보조 배열을 실제로 정의할 수 있습니다.
public class Test {
private final String[] original;
private final String[] auxiliary;
/** constructor */
public Test(String[] _values) {
original = new String[_values.length];
// Pre-allocated array.
auxiliary = new String[_values.length];
System.arraycopy(_values, 0, original, 0, _values.length);
}
/** Get array values. */
public String[] getValues() {
// No need to call clone() - we pre-allocated auxiliary.
System.arraycopy(original, 0, auxiliary, 0, original.length);
return auxiliary;
}
}
테스트 방법:
Test test = new Test(new String[]{"a", "b", "C"});
System.out.println(Arrays.asList(test.getValues()));
String[] values = test.getValues();
values[0] = "foobar";
// At this point, "foobar" exist in "auxiliary" but since we are
// copying "original" to "auxiliary" for each call, the next line
// will print the original values "a", "b", "c".
System.out.println(Arrays.asList(test.getValues()));
완벽하지는 않지만 적어도 (클래스의 관점에서) "의사 불변 어레이"를 가지고 있기 때문에 관련 코드가 끊어지지 않습니다.
java.util.function.IntUnaryOperator
:
class ImmutableArray implements IntUnaryOperator {
private final int[] array;
ImmutableArray(int[] array) {
this.array = Arrays.copyOf(array, array.length);
}
@Override
public int applyAsInt(int index) {
return array[index];
}
}
array[i]
becomes가 되다immutableArray.applyAsInt(i)
.
- 100_000_000 요소를 가진 계수 연산을 사용하여 루프 검색을 위한 프리미티브를 벤치마킹했습니다.의 「 」
PrimitiveArray
최대 220ms가 소요되었으며 원시 배열과 큰 차이는 없었습니다.같은 조작은ArrayList
처리에는 로드 , 이 설정을 했습니다.Primitive Array primitive초2 초초초2 초 primitive primitive 。
반복
만약 당신이 반복하고 싶다면, 반복하고 싶은 경우는,실장해 주세요를 구현합니다.
Iterable
그리고 provide제공하다public java.util.PrimitiveIterator.OfInt iterator() { return Arrays.stream(array).iterator(); }
이 이를통해 에에 대한 액세스수 있습니다 할 액세스를 제공한다.
int nextInt
방법.방법.부터부터
PrimitiveIterator
또한 메서드당신도방법이 있단다.forEachRemaining(PrimitiveConsumer)
이는 루프를 강화된 기존 대체하는데 도움이 된다.루프를 대체하는에이는 기존의 확장도움이 됩니다 데.수동으로를 사용하여와 Iterating 수동으로 반복
PrimitiveIterator.OfInt
~300ms의 Yielded 공연이다.최대 300ms의 성능을 발휘합니다.
배열은 변종 파라미터로 상수로 전달하면 편리합니다.
언급URL : https://stackoverflow.com/questions/3700971/immutable-array-in-java
'programing' 카테고리의 다른 글
함수 호출이 현대 플랫폼에 효과적인 메모리 장벽입니까? (0) | 2022.08.02 |
---|---|
Foreach(Vuex)의 상태로부터 요소를 참조하려면 어떻게 해야 합니까? (0) | 2022.08.02 |
JSON 데이터를 Java 개체로 변환하는 중 (0) | 2022.07.19 |
Vuejs - vuex 계산 속성, DOM이 업데이트되지 않음 (0) | 2022.07.19 |
VueJ에서 렌더링 목록 항목의 innerText를 가져오는 방법s (0) | 2022.07.19 |