44

リストまたはセットのすべての要素を小文字にする最も効率的な方法は何ですか?

リストに関する私の考え:

final List<String> strings = new ArrayList<String>();
strings.add("HELLO");
strings.add("WORLD");

for(int i=0,l=strings.size();i<l;++i)
{
  strings.add(strings.remove(0).toLowerCase());
}

より良い、より速い方法はありますか?セットの場合、この例はどのようになりますか?現在、セット(またはリスト)の各要素に操作を適用する方法がないため、追加の一時セットを作成せずに操作を実行できますか?

このようなものがいいでしょう:

Set<String> strings = new HashSet<String>();
strings.apply(
  function (element)
  { this.replace(element, element.toLowerCase();) } 
);

ありがとう、

4

11 に答える 11

117

さらに別の解決策ですが、Java8以降を使用します。

List<String> result = strings.stream()
                             .map(String::toLowerCase)
                             .collect(Collectors.toList());
于 2015-06-28T20:05:36.060 に答える
32

これは、リストにとってかなりクリーンなソリューションのようです。特定のリスト実装を使用して、線形時間でのリストのトラバースと定数時間での文字列の置換の両方に最適な実装を提供できるようにする必要があります。

public static void replace(List<String> strings)
{
    ListIterator<String> iterator = strings.listIterator();
    while (iterator.hasNext())
    {
        iterator.set(iterator.next().toLowerCase());
    }
}

これは私がセットのために思いつくことができる最高です。他の人が言っているように、操作はいくつかの理由でセット内でインプレースで実行することはできません。小文字の文字列は、置換する文字列とは異なる場所に配置する必要がある場合があります。さらに、小文字の文字列は、すでに追加されている別の小文字の文字列と同一である場合、セットにまったく追加されない可能性があります(たとえば、「HELLO」と「Hello」は両方とも「hello」を生成します。セットに追加されるのは1回だけです)。

public static void replace(Set<String> strings)
{
    String[] stringsArray = strings.toArray(new String[0]);
    for (int i=0; i<stringsArray.length; ++i)
    {
        stringsArray[i] = stringsArray[i].toLowerCase();
    }
    strings.clear();
    strings.addAll(Arrays.asList(stringsArray));
}
于 2010-04-15T11:16:36.030 に答える
13

あなたはGoogleコレクションでこれを行うことができます:

    Collection<String> lowerCaseStrings = Collections2.transform(strings,
        new Function<String, String>() {
            public String apply(String str) {
                return str.toLowerCase();
            }
        }
    );
于 2010-04-15T11:22:41.133 に答える
5

入力リストを変更しても問題がない場合は、ここでそれを実現するもう1つの方法があります。

strings.replaceAll(String::toLowerCase)

于 2019-01-09T08:07:08.247 に答える
4

ええと、2つの事実のために本当のエレガントな解決策はありません:

  • StringJavaのsは不変です
  • Javaはmap(f, list)、関数型言語のように本当に素晴らしい機能を提供しません。

漸近的に言えば、現在の方法よりも優れた実行時間を得ることはできません。を使用して新しい文字列を作成するtoLowerCase()必要があります。また、リストを自分で繰り返して、新しい小文字の文字列を生成し、既存の文字列に置き換える必要があります。

于 2010-04-15T11:10:03.007 に答える
2

インプレースソリューションの場合はCommonsCollectionsのCollectionUtils#transformを、ライブビューが必要な場合はGuavaのCollections2 #transformを試してください。

于 2010-04-15T11:14:18.373 に答える
1

これはおそらくより高速です:

for(int i=0,l=strings.size();i<l;++i)
{
  strings.set(i, strings.get(i).toLowerCase());
}
于 2010-04-15T11:04:23.080 に答える
0

文字列をセットに変更した場合、(別のコレクションを作成せずに)その場で操作を行うことはできないと思います。これは、イテレータまたはfor eachループを使用してのみセットを反復処理でき、その間は新しいオブジェクトを挿入できないためです(例外がスローされます)。

于 2010-04-15T11:14:55.210 に答える
0

受け入れられた(Matthew T. Staeblerの)ソリューションでListIteratorメソッドを参照します。ここでの方法よりもListIteratorをどのように使用するのが良いですか?

public static Set<String> replace(List<String> strings) {
    Set<String> set = new HashSet<>();
    for (String s: strings)
        set.add(s.toLowerCase());
    return set;
}
于 2012-05-07T22:25:35.313 に答える
0

私は似たようなものを探していましたが、ArrayListオブジェクトがGENERICとして宣言されておらず、どこかから生のList型オブジェクトとして利用可能だったために行き詰まりました。ArrayListオブジェクト「_products」を取得していました。だから、私がしたことは以下に述べられており、それは私にとって完璧に機能しました::

List<String> dbProducts = _products;
    for(int i = 0; i<dbProducts.size(); i++) {
        dbProducts.add(dbProducts.get(i).toLowerCase());         
    }

つまり、最初に使用可能な_productsを取得し、GENERICリストオブジェクトを作成し(同じ文字列のみを取得していたため)、非ジェネリックArrayListオブジェクトのために以前は機能していなかったリスト要素にtoLowerCase()メソッドを適用しました。

そして、ここで使用しているtoLowerCase()メソッドはStringクラスです。

文字列java.lang.String.toLowerCase()

ArrayListまたはObjectクラスではありません。

mが間違っている場合は修正してください。JAVAの初心者はガイダンスを求めています。:)

于 2015-12-18T12:08:57.987 に答える
0

JAVA 8並列ストリームを使用すると、高速になります

List<String> output= new ArrayList<>();
List<String> input= new ArrayList<>();
input.add("A");
input.add("B");
input.add("C");
input.add("D");
input.stream().parallel().map((item) -> item.toLowerCase())
            .collect(Collectors.toCollection(() -> output));
于 2016-08-05T10:31:57.520 に答える