整数のリストがあり、List<Integer>
すべての整数オブジェクトを文字列に変換して、新しいで仕上げたいと思いますList<String>
。
当然のことながら、新しい整数を作成List<String>
してリストをループすることで新しいループを作成することもできましたString.valueOf()
が、それを行うためのより良い(より自動化された)方法があるかどうか疑問に思っていましたか?
整数のリストがあり、List<Integer>
すべての整数オブジェクトを文字列に変換して、新しいで仕上げたいと思いますList<String>
。
当然のことながら、新しい整数を作成List<String>
してリストをループすることで新しいループを作成することもできましたString.valueOf()
が、それを行うためのより良い(より自動化された)方法があるかどうか疑問に思っていましたか?
回答:
私の知る限り、これを行う唯一の方法は、反復してインスタンス化することです。次のようなもの(他の潜在的な助けのために、これを行う方法を知っていると確信しています):
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));
}
使用グアバ-プロジェクトからGoogleのコレクションを、あなたが使用できる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
あるビューバッキングリストの-変換は、変換されたリストへの各アクセスに適用されます。
はnullに適用されるFunctions.toStringFunction()
とをスローすることに注意してください。そのNullPointerException
ため、リストに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の関数ライブラリでサポートされていない変換では短くなります。カスタム関数はまだ簡単ですが、このJava 8ストリームよりもはるかに多くのコードです
あなたがやっていることは結構ですが、あなたは「Javaにそれアップ」の必要性を感じる場合は使用することができ変圧器および収集方法からのApache Commonsの、例えば:
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コレクションを使用している場合に考慮すべきこと。
jsightの答えで「ボクシング」について心配している人々には、何もありません。String.valueOf(Object)
ここで使用され、へのボックス化解除int
は実行されません。
使用するInteger.toString()
か、String.valueOf(Object)
可能なnullを処理する方法に依存するかどうか。例外をスローするか(おそらく)、リストに「null」の文字列を含めますか(たぶん)。前者の場合、NullPointerException
またはその他のタイプをスローしますか?
また、jsightの応答の小さな欠点の1つList
はインターフェースであり、それにnew演算子を使用できません。私はおそらくjava.util.ArrayList
この場合にa を使用するでしょう。特に、リストがどれくらいの長さであるかを前もって知っているからです。
デバッグ以外の目的でObject.toString()を使用することは、この2つの機能が同等であるとしても(リストにnullがないと仮定して)、おそらく非常に悪い考えだと思います。標準ライブラリのクラスのtoString()メソッドを含め、開発者は警告なしにtoString()メソッドの動作を自由に変更できます。
ボックス化/ボックス化解除プロセスによって引き起こされるパフォーマンスの問題についても心配しないでください。パフォーマンスが重要な場合は、アレイを使用してください。それが本当に重要な場合は、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のリストがあり、それらを対応するString表現に変換したい場合、次のように記述できます。
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();
}
ストリームの使用:結果が整数のリスト(List<Integer> result
)であるとすると、次のようになります。
List<String> ids = (List<String>) result.stream().map(intNumber -> Integer.toString(intNumber)).collect(Collectors.toList());
それを解決する方法の1つ。お役に立てれば。
ただ面白くするために、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バージョンが登場すると、速度のメリットなどすべてが得られます。
私がジャカルタコレクションを愛しているのと同じくらい、それらはGenericsをサポートせず、LCDとして1.4を使用しています。Googleコレクションはアルファサポートレベルとしてリストされているため、注意が必要です。
私は問題に対するオブジェクト指向の解決策を取り入れたいと思っていました。
ドメインオブジェクトをモデル化する場合、ソリューションはドメインオブジェクト内にあります。ここでのドメインは、文字列値が必要な整数のリストです。
最も簡単な方法は、リストをまったく変換しないことです。
つまり、変換せずに変換するには、元の整数のリストを値のリストに変更します。値は次のようになります...
class Value {
Integer value;
public Integer getInt()
{
return value;
}
public String getString()
{
return String.valueOf(value);
}
}
これは、リストをコピーするよりも速く、メモリ使用量も少なくなります。
幸運を!