목록을 변환하는 방법Java에서 int []? [복제]
이 질문에는 이미 답변이 있습니다.
이것은이 질문과 비슷합니다 : Java에서 int []를 Integer []로 변환하는 방법은 무엇입니까?
Java를 처음 사용합니다. 어떻게는 변환 할 수 있습니다 List<Integer>
에 int[]
자바로? List.toArray()
실제로 Object[]
nether Integer[]
또는 로 캐스팅 할 수있는을 반환 하기 때문에 혼란 스럽습니다 int[]
.
지금은 루프를 사용하여 그렇게하고 있습니다.
int[] toIntArray(List<Integer> list){
int[] ret = new int[list.size()];
for(int i = 0;i < ret.length;i++)
ret[i] = list.get(i);
return ret;
}
더 좋은 방법이 있다고 확신합니다.
불행히도 Java가 기본 유형, 복싱, 배열 및 제네릭을 처리하는 특성으로 인해 실제로이 작업을 수행하는 더 좋은 방법 은 없다고 생각 합니다. 특히:
List<T>.toArray
에서Integer
로 변환이 없기 때문에 작동하지 않습니다int
- 당신은 사용할 수 없습니다
int
는 것, 그래서 제네릭 형식 인수로 이 로int
- 특정 방법 (또는 더러운 속임수를 수행하는 데 사용되는 반사 하나).
모든 기본 유형에 대해 이러한 종류의 방법의 자동 생성 버전을 가진 라이브러리가 있다고 생각합니다 (즉, 각 유형마다 복사되는 템플릿이 있습니다). 그것은 추악하지만 그것이 내가 두려워하는 방식입니다 :(
짝수하지만 Arrays
클래스는 자바에 도착 제네릭 전에 나왔다가 (당신이 원시적 배열을 사용하고자하는 가정) 오늘 소개 된 경우, 여전히 모든 끔찍한 과부하를 포함해야합니다.
Java 8에는 아직 언급 된 스트림이 없으므로 여기에갑니다.
int[] array = list.stream().mapToInt(i->i).toArray();
생각 과정 :
- simple
Stream#toArray
returnsObject[]
이므로 원하는 것이 아닙니다. 또한Stream#toArray(IntFunction<A[]> generator)
제네릭 형식이 있기 때문에 우리가 원하는 것을하지 않는A
원시 나타낼 수 없습니다int
- 따라서
int
래퍼 대신 기본 유형을 처리 할 수있는 스트림을 갖는 것이 좋을 것입니다Integer
. 왜냐하면toArray
메소드는int[]
배열 을 반환 할 가능성이 높기 때문에 ( 여기서Object[]
또는 상자 모양의 것을 반환하는 것은Integer[]
부자연 스럽습니다). 다행히도 Java 8에는 이러한 스트림이 있습니다.IntStream
이제 우리가 알아 내야 할 것은 우리
Stream<Integer>
(list.stream()
그것 에서 반환 될 )를 반짝 로 변환하는 방법IntStream
입니다. 여기에Stream#mapToInt(ToIntFunction<? super T> mapper)
방법이 구출됩니다. 우리가해야 할 일은 그것에서 매핑에 전달됩니다Integer
에int
. 우리는 다음과 같은Integer#getValue
것을 반환 할 수 있습니다int
:mapToInt( (Integer i) -> i.intValue() )
(또는 누군가가 선호하는 경우
mapToInt(Integer::intValue)
)그러나 컴파일러는이 람다의 결과가 있어야한다는 것을 알고 있기 때문에 unboxing을 사용하여 유사한 코드를 생성 할 수 있습니다
int
(lambda는 반환 될 메소드의 본문을 기대mapToInt
하는ToIntFunction
인터페이스의 구현입니다 ).int applyAsInt(T value)
int
그래서 우리는 간단히 쓸 수 있습니다
mapToInt((Integer i)->i)
또한
Integer
type in(Integer i)
은 컴파일러에서 유추 할 수 있기 때문에List<Integer>#stream()
반환Stream<Integer>
할 수 있기 때문에 건너 뛸 수 있습니다.mapToInt(i -> i)
Commons Lang 외에도 Guava 의 방법 으로이 작업을 수행 할 수 있습니다 Ints.toArray(Collection<Integer> collection)
.
List<Integer> list = ...
int[] ints = Ints.toArray(list);
이를 통해 Commons Lang과 동등한 중간 배열 변환을 수행 할 필요가 없습니다.
가장 쉬운 방법은 Apache Commons Lang을 사용하는 것입니다 . 그것은 당신이 원하는 것을 할 수있는 편리한 ArrayUtils 클래스를 가지고 있습니다. s toPrimitive
배열에 과부하가있는 방법을 사용하십시오 Integer
.
List<Integer> myList;
... assign and fill the list
int[] intArray = ArrayUtils.toPrimitive(myList.toArray(new Integer[myList.size()]));
이렇게하면 바퀴를 재발 명하지 않습니다. Commons Lang은 Java가 빼 놓은 많은 유용한 것들을 가지고 있습니다. 위에서 올바른 크기의 정수 목록을 만들었습니다. 길이가 0 인 정적 정수 배열을 사용하여 Java가 올바른 크기의 배열을 할당하도록 할 수도 있습니다.
static final Integer[] NO_INTS = new Integer[0];
....
int[] intArray2 = ArrayUtils.toPrimitive(myList.toArray(NO_INTS));
Java 8 은 스트림을 통해이 작업을 수행하는 쉬운 방법을 제공했습니다 ...
collections stream()
함수를 사용하고 int에 매핑하면 IntStream이 생깁니다. 로 IntStream
toArray ()를 호출하면int []
int [] ints = list.stream().mapToInt(Integer::intValue).toArray();
int[] toIntArray(List<Integer> list) {
int[] ret = new int[list.size()];
int i = 0;
for (Integer e : list)
ret[i++] = e;
return ret;
}
값 비싼 목록 인덱싱을 피하기 위해 코드를 약간 변경하십시오 (List는 반드시 ArrayList가 아니지만 무작위 액세스가 비싼 링크 된 목록 일 수 있기 때문에)
여기에 Java 8 단일 라인 코드가 있습니다.
public int[] toIntArray(List<Integer> intList){
return intList.stream().mapToInt(Integer::intValue).toArray();
}
여기에 하나 더 던져 줄 게요. for 루프를 여러 번 사용하는 것을 보았지만 루프 내부에 아무것도 필요하지 않습니다. 원래 질문이 덜 장황한 코드를 찾으려고했기 때문에 이것을 언급했습니다.
int[] toArray(List<Integer> list) {
int[] ret = new int[ list.size() ];
int i = 0;
for( Iterator<Integer> it = list.iterator();
it.hasNext();
ret[i++] = it.next() );
return ret;
}
Java가 for 루프에서 C ++처럼 여러 선언을 허용하면 한 단계 더 나아가 for (int i = 0, Iterator it ...
결국 (이 부분은 제 의견입니다), 당신을 위해 무언가를하는 데 도움이되는 기능이나 방법을 가지려면, 그것을 설정하고 잊어 버려요. 1 개의 라이너 또는 10 개일 수 있습니다. 다시 보지 않으면 차이를 알 수 없습니다.
당신은 단순히 매핑하는 경우 Integer
로를 int
당신은 고려해야 병렬 처리를 사용 하여 매핑 로직의 범위를 벗어난 변수에 의존하지 않기 때문에.
int[] arr = list.parallelStream().mapToInt(Integer::intValue).toArray();
이걸 알아 둬
병렬 처리는 데이터 및 프로세서 코어가 충분한 경우에도 직렬로 작업을 수행하는 것보다 자동으로 빠르지 않습니다. 집계 작업을 통해 병렬 처리를보다 쉽게 구현할 수 있지만 응용 프로그램이 병렬 처리에 적합한 지 결정하는 것은 여전히 귀하의 책임입니다.
정수를 기본 형식으로 맵핑하는 두 가지 방법이 있습니다.
를 통해
ToIntFunction
.mapToInt(Integer::intValue)
람다 식의 명시 적 언 박싱 을 통해 .
mapToInt(i -> i.intValue())
람다 식의 암시 적 (자동) 언 박싱을 통해.
mapToInt(i -> i)
null
값이 있는 목록이 주어짐
List<Integer> list = Arrays.asList(1, 2, null, 4, 5);
처리 할 옵션은 다음과 같습니다 null
.
null
매핑하기 전에 값을 필터링하십시오 .int[] arr = list.parallelStream().filter(Objects::nonNull).mapToInt(Integer::intValue).toArray();
null
값을 기본값으로 맵핑하십시오 .int[] arr = list.parallelStream().map(i -> i == null ? -1 : i).mapToInt(Integer::intValue).toArray();
null
람다 식 내부를 처리 하십시오.int[] arr = list.parallelStream().mapToInt(i -> i == null ? -1 : i.intValue()).toArray();
이 간단한 루프는 항상 정확합니다! 버그 없음
int[] integers = new int[myList.size()];
for (int i = 0; i < integers.length; i++) {
integers[i] = myList.get(i);
}
toArray가 Object []를 리턴하고 Object []에서 int []로 또는 Integer []에서 int []로 캐스트 할 수 없으므로 수행하려는 작업을 "한 줄로 묶는"방법이 없습니다.
int[] ret = new int[list.size()];
Iterator<Integer> iter = list.iterator();
for (int i=0; iter.hasNext(); i++) {
ret[i] = iter.next();
}
return ret;
import static com.humaorie.dollar.Dollar.*
...
List<Integer> source = ...;
int[] ints = $(source).convert().toIntArray();
함께 이클립스 컬렉션 이 유형의 목록이있는 경우, 다음을 수행 할 수 있습니다 java.util.List<Integer>
:
List<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = LazyIterate.adapt(integers).collectInt(i -> i).toArray();
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
이미 Eclipse Collections 유형 MutableList
이있는 경우 다음을 수행 할 수 있습니다.
MutableList<Integer> integers = Lists.mutable.with(1, 2, 3, 4, 5);
int[] ints = integers.asLazy().collectInt(i -> i).toArray();
Assert.assertArrayEquals(new int[]{1, 2, 3, 4, 5}, ints);
참고 : 저는 Eclipse Collections의 커미터입니다.
List<?>
java collections API에서 골격 구현 을 사용하는 것이 좋습니다 .이 특별한 경우에는 매우 도움이되는 것으로 보입니다.
package mypackage;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Test {
//Helper method to convert int arrays into Lists
static List<Integer> intArrayAsList(final int[] a) {
if(a == null)
throw new NullPointerException();
return new AbstractList<Integer>() {
@Override
public Integer get(int i) {
return a[i];//autoboxing
}
@Override
public Integer set(int i, Integer val) {
final int old = a[i];
a[i] = val;//auto-unboxing
return old;//autoboxing
}
@Override
public int size() {
return a.length;
}
};
}
public static void main(final String[] args) {
int[] a = {1, 2, 3, 4, 5};
Collections.reverse(intArrayAsList(a));
System.out.println(Arrays.toString(a));
}
}
복싱 / 언 박싱 단점에주의
람다를 사용하면 이렇게 할 수 있습니다 (jdk 람다에서 컴파일).
public static void main(String ars[]) {
TransformService transformService = (inputs) -> {
int[] ints = new int[inputs.size()];
int i = 0;
for (Integer element : inputs) {
ints[ i++ ] = element;
}
return ints;
};
List<Integer> inputs = new ArrayList<Integer>(5) { {add(10); add(10);} };
int[] results = transformService.transform(inputs);
}
public interface TransformService {
int[] transform(List<Integer> inputs);
}
참고 URL : https://stackoverflow.com/questions/960431/how-to-convert-listinteger-to-int-in-java
'development' 카테고리의 다른 글
Docker 컨테이너의 파일 시스템 탐색 (0) | 2020.02.10 |
---|---|
다형성이란 무엇이며, 그 목적은 무엇이며 어떻게 사용됩니까? (0) | 2020.02.10 |
UIViewController의보기가 보이는지 확인하는 방법 (0) | 2020.02.10 |
채워지지 않은 JavaScript 배열을 만드는 가장 효율적인 방법은 무엇입니까? (0) | 2020.02.10 |
렌더링 후 입력에 초점 설정 (0) | 2020.02.10 |