정수 목록이 있고 List<Integer>
모든 정수 개체를 문자열로 변환하여 새로운 List<String>
.
당연히 새를 만들고 각 정수를 List<String>
호출하는 목록을 반복 할 수 String.valueOf()
있지만 더 나은 (read : more automatic ) 방법 이 있는지 궁금 합니다.
정수 목록이 있고 List<Integer>
모든 정수 개체를 문자열로 변환하여 새로운 List<String>
.
당연히 새를 만들고 각 정수를 List<String>
호출하는 목록을 반복 할 수 String.valueOf()
있지만 더 나은 (read : more automatic ) 방법 이 있는지 궁금 합니다.
답변:
내가 아는 한, 반복하고 인스턴스화하는 것이 이것을 수행하는 유일한 방법입니다. 다음과 같은 것 (다른 사람에게 도움이 될 수있는 방법을 알고 계실 것입니다) :
List<Integer> oldList = ...
/* Specify the size of the list up front to prevent resizing. */
List<String> newList = new ArrayList<>(oldList.size());
for (Integer myInt : oldList) {
newList.add(String.valueOf(myInt));
}
사용 구아바 - 프로젝트에서 구글 컬렉션 , 당신은 사용할 수 transform
의 방법을 나열 클래스
import com.google.common.collect.Lists;
import com.google.common.base.Functions
List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = Lists.transform(integers, Functions.toStringFunction());
에서 List
반환 된 transform
것은 백업 목록 의 보기 입니다. 변환은 변환 된 목록에 대한 각 액세스에 적용됩니다.
그주의 Functions.toStringFunction()
발생합니다 NullPointerException
확실 목록이 null이 포함되지 않습니다 경우 그렇게 밖에 이용, 널 (null)에 적용 할 때.
Java 8을위한 솔루션입니다. Guava보다 약간 길지만 최소한 라이브러리를 설치할 필요는 없습니다.
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
//...
List<Integer> integers = Arrays.asList(1, 2, 3, 4);
List<String> strings = integers.stream().map(Object::toString)
.collect(Collectors.toList());
toString
예제에서는 조금 더 길지만 Guava의 Functions 라이브러리에서 지원하지 않는 변환의 경우 더 짧아집니다. 사용자 정의 함수는 여전히 쉽지만이 Java 8 스트림보다 훨씬 많은 코드입니다
당신이하고있는 일은 괜찮지 만 'Java-it-up'이 필요하다고 느끼면 Transformer 와 Apache Commons 의 collect 메소드 를 사용할 수 있습니다. 예 :
public class IntegerToStringTransformer implements Transformer<Integer, String> {
public String transform(final Integer i) {
return (i == null ? null : i.toString());
}
}
..그리고..
CollectionUtils.collect(
collectionOfIntegers,
new IntegerToStringTransformer(),
newCollectionOfStrings);
String.valueOf를 사용하는 대신 .toString (); @ johnathan.holland가 설명하는 일부 자동 복싱을 피합니다.
javadoc은 valueOf가 Integer.toString ()과 같은 것을 반환한다고 말합니다.
List<Integer> oldList = ...
List<String> newList = new ArrayList<String>(oldList.size());
for (Integer myInt : oldList) {
newList.add(myInt.toString());
}
Guava 및 Java 8을 사용하는 또 다른 솔루션
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<String> strings = Lists.transform(numbers, number -> String.valueOf(number));
핵심 Java가 아니고 일반화되지 않았지만 인기있는 Jakarta commons collections 라이브러리에는 이러한 종류의 작업에 대한 몇 가지 유용한 추상화가 있습니다. 특히, 수집 방법을 살펴보십시오.
프로젝트에서 이미 커먼즈 컬렉션을 사용하고 있다면 고려해야 할 사항입니다.
jsight의 대답에서 "권투"에 대해 우려하는 사람들에게 : 아무것도 없습니다. String.valueOf(Object)
여기서 사용되며 unboxing int
은 수행 되지 않습니다 .
사용 여부 Integer.toString()
또는 String.valueOf(Object)
가능한 null을 처리하려는 방법에 따라 다릅니다. 예외 (아마도)를 던지거나 목록에 "null"문자열을 포함 하시겠습니까 (아마도). 전자라면, NullPointerException
다른 유형 을 던지고 싶 습니까?
또한 jsight의 응답에서 한 가지 작은 결함 List
은 인터페이스입니다. 새 연산자를 사용할 수 없습니다. java.util.ArrayList
이 경우에는 아마도 a 를 사용할 것입니다 . 특히 목록이 얼마나 오래 걸릴지 미리 알고 있기 때문입니다.
디버깅 이외의 목적으로 Object.toString ()을 사용하는 것은 아마도이 경우 두 가지가 기능적으로 동일하더라도 (목록에 null이 없다고 가정) 정말 나쁜 생각이라고 생각합니다. 개발자는 표준 라이브러리에있는 모든 클래스의 toString () 메서드를 포함하여 경고없이 모든 toString () 메서드의 동작을 자유롭게 변경할 수 있습니다.
boxing / unboxing 프로세스로 인한 성능 문제에 대해 걱정하지 마십시오. 성능이 중요한 경우 어레이를 사용하십시오. 정말 중요하다면 Java를 사용하지 마십시오. JVM을 능가하려는 시도는 고통을 초래할뿐입니다.
전문가를위한 답변 :
List<Integer> ints = ...;
String all = new ArrayList<Integer>(ints).toString();
String[] split = all.substring(1, all.length()-1).split(", ");
List<String> strs = Arrays.asList(split);
String
)은 동일한 백업 배열 (에서 all
) 을 공유 하므로 실제로 메모리 효율성이 매우 뛰어나며 장기적인 성능에 중요합니다. 물론 요소 중 하나만 유지하고 싶지 않다면 ...
Lambdaj 는 매우 간단하고 읽기 쉬운 방식으로이를 수행 할 수 있습니다. 예를 들어, Integer 목록이 있고 해당 문자열 표현으로 변환하려는 경우 다음과 같이 작성할 수 있습니다.
List<Integer> ints = asList(1, 2, 3, 4);
Iterator<String> stringIterator = convertIterator(ints, new Converter<Integer, String> {
public String convert(Integer i) { return Integer.toString(i); }
}
Lambdaj는 결과를 반복하는 동안에 만 변환 함수를 적용합니다.
"박싱 오버 헤드"를 피할 수 없습니다. Java의 가짜 제네릭 컨테이너는 객체 만 저장할 수 있으므로 int는 Integer로 박스해야합니다. 원칙적으로 Object에서 Integer 로의 다운 캐스트를 피할 수 있지만 (Object가 String.valueOf와 Object.toString 모두에 충분하기 때문에 무의미하기 때문에) 컴파일러가 그렇게 할 수있을만큼 똑똑한지는 모르겠습니다. String에서 Object 로의 변환은 다소 무의미해야하므로 걱정할 필요가 없습니다.
나는 공간 복잡성의 원칙을 따르는 해결책을 보지 못했습니다. 정수 목록에 많은 수의 요소가 있으면 큰 문제입니다.
It will be really good to remove the integer from the List<Integer> and free
the space, once it's added to List<String>.
반복자를 사용하여 동일한 결과를 얻을 수 있습니다.
List<Integer> oldList = new ArrayList<>();
oldList.add(12);
oldList.add(14);
.......
.......
List<String> newList = new ArrayList<String>(oldList.size());
Iterator<Integer> itr = oldList.iterator();
while(itr.hasNext()){
newList.add(itr.next().toString());
itr.remove();
}
재미를 위해 JDK7에 있어야하는 jsr166y fork-join 프레임 워크를 사용하는 솔루션입니다.
import java.util.concurrent.forkjoin.*;
private final ForkJoinExecutor executor = new ForkJoinPool();
...
List<Integer> ints = ...;
List<String> strs =
ParallelArray.create(ints.size(), Integer.class, executor)
.withMapping(new Ops.Op<Integer,String>() { public String op(Integer i) {
return String.valueOf(i);
}})
.all()
.asList();
(면책 조항 : 컴파일되지 않음. 사양이 확정되지 않았습니다. 등)
JDK7에있을 것 같지 않은 것은 withMapping 호출을 덜 장황하게 만드는 약간의 유형 추론 및 구문 적 설탕입니다.
.withMapping(#(Integer i) String.valueOf(i))
이것은 외부 라이브러리를 사용하지 않는 기본적인 작업입니다 (프로젝트에 필요하지 않은 종속성이 발생합니다).
이러한 종류의 작업을 수행하도록 특별히 제작 된 정적 메서드 클래스가 있습니다. 코드가 너무 간단하기 때문에 Hotspot이 최적화를 수행하도록했습니다. 이것은 최근에 내 코드의 테마 인 것 같습니다. 매우 간단한 (간단한) 코드를 작성하고 Hotspot이 마법을 수행하도록합니다. 이와 같은 코드와 관련하여 성능 문제는 거의 발생하지 않습니다. 새 VM 버전이 출시되면 모든 추가 속도 이점 등을 얻을 수 있습니다.
내가 Jakarta 컬렉션을 좋아하는만큼 Generics를 지원하지 않고 LCD로 1.4를 사용합니다. Google 컬렉션은 알파 지원 수준으로 표시되기 때문에 조심합니다!
나는 문제에 대한 객체 지향 솔루션으로 차임하고 싶었습니다.
도메인 개체를 모델링하는 경우 솔루션은 도메인 개체에 있습니다. 여기서 도메인은 문자열 값을 원하는 정수 목록입니다.
가장 쉬운 방법은 목록을 전혀 변환하지 않는 것입니다.
즉, 변환하지 않고 변환하려면 원래 Integer 목록을 List of Value로 변경하십시오. 여기서 Value는 다음과 같습니다.
class Value {
Integer value;
public Integer getInt()
{
return value;
}
public String getString()
{
return String.valueOf(value);
}
}
이것은 목록을 복사하는 것보다 빠르며 메모리를 덜 차지합니다.
행운을 빕니다!