質問

整数のリストがありますが、 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<String>(oldList.size()) 
for (Integer myInt : oldList) { 
  newList.add(String.valueOf(myInt)); 
}

他のヒント

使用する Guava プロジェクトの 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 です ビュー バッキング リスト上 - 変換は、変換されたリストへのアクセスごとに適用されます。

を注意 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());

あなたがやっていることは問題ありませんが、「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 のソースは次のようになります。

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

それほど重要ではありませんが、私なら toString を使用します。

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()); 
}

ここでは、非 JDK ライブラリを使用して不正行為を行わないワンライナーの解決策を示します。

List<String> strings = Arrays.asList(list.toString().replaceAll("\\[(.*)\\]", "$1").split(", "));

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 ライブラリには、この種のタスクに役立つ抽象化がいくつかあります。具体的には、collect メソッドを参照してください。

コレクションユーティリティ

プロジェクトですでにコモンズ コレクションを使用している場合は考慮すべき点があります。

jsight の回答の「ボクシング」について懸念している人々へ:なにもない。 String.valueOf(Object) ここでは使用されており、開梱する必要はありません int はこれまでに実行されます。

使用するかどうか Integer.toString() または String.valueOf(Object) 可能性のある null をどのように処理するかによって異なります。例外をスローしますか (おそらく)、リストに "null" 文字列を入れますか (おそらく)。前者の場合、を投げますか? NullPointerException それとも他のタイプですか?

また、jsight の応答には小さな欠陥が 1 つあります。 List はインターフェイスなので、 new 演算子を使用することはできません。おそらく使用すると思います java.util.ArrayList この場合、特にリストがどのくらい長くなる可能性があるかを事前に知っているためです。

@ジョナサン:間違っている可能性がありますが、この場合の String.valueOf() は String.valueOf(int) にボックス化されるのではなく、 String.valueOf(Object) 関数を呼び出すと思います。String.valueOf(Object) は、null の場合は「null」を返すだけで、null 以外の場合は Object.toString() を呼び出します。これにはボックス化は含まれません (ただし、新しい文字列オブジェクトのインスタンス化は明らかに含まれます)。

デバッグ以外の目的で 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);

ラムダージ 非常にシンプルで読みやすい方法でそれを行うことができます。たとえば、整数のリストがあり、それらを対応する文字列表現に変換したいとすると、次のような記述が可能です。

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 へのダウンキャストを回避できます (String.valueOf と Object.toString の両方に Object が十分に適しているため、意味がありません) が、コンパイラーがそれを行うのに十分な賢さがあるかどうかはわかりません。String から Object への変換は多かれ少なかれ何も操作を行わないはずなので、それについて心配する気はありません。

楽しみのために、JDK7 に含まれる jsr166y フォーク結合フレームワークを使用したソリューションを紹介します。

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 コレクションが大好きですが、それらはジェネリックをサポートしておらず、LCD として 1.4 を使用しています。Google コレクションはサポート レベルがアルファ版としてリストされているため、注意してください。

スペースの原則に従った解決策は見当たらない。 複雑さだ。整数のリストの要素数が多ければ、それは 大きな問題だ。

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();
    }

私はこの問題に対するオブジェクト指向の解決策を提案したかっただけです。

ドメイン オブジェクトをモデル化する場合、ソリューションはドメイン オブジェクトにあります。ここでのドメインは、文字列値が必要な整数のリストです。

最も簡単な方法は、リストをまったく変換しないことです。

とはいえ、変換せずに変換するには、元の Integer のリストを Value のリストに変更します。Value は次のようになります...

class Value {
    Integer value;
    public Integer getInt()
    {
       return value;
    }
    public String getString()
    {
       return String.valueOf(value);
    }
}

これは、リストをコピーするよりも高速で、使用するメモリも少なくなります。

幸運を!

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top