2016-11-19 19 views
-2

私は大きな文字列を含むArrayListを持っています。要素が合致する条件に基づいて分割したいたとえば、ArrayListにStringが含まれている場合は、文字列の長さにすることができます。それを行う最も効率的な方法は何ですか?条件に基づいて複数の1にArrayListを分割します

['a', 'bc', 'defe', 'dsa', 'bb'] 

につながる後:

['a'], ['bc', 'bb'], ['dsa'], ['defe'] 
+0

近い条件を指定:あります最適化は不可能ですが、あなたはブルートフォースで解決しなければなりません。それぞれのデータ構造を少し最適化することができますが、マッチング自体は、実行されたアトリビュートを知らなくても最適化することはできません。 – Paul

+0

条件は何ですか? 'bc'と' bb'は一緒にグループ化されていますが、 'dsa'と' defe'はグループ化されていませんか? – SergeyB

+0

@ike_loveこれは、質問テキストで与えられた例に従います。文字列*長さ*でグループ化されています。 – Andreas

答えて

1

最も効率的な方法は、一度だけ元のリストを反復することです。あなたは、バケットを作成してそれらのバケットに追加することができます。

public class Q1 {  
    public static void main(String[] args) { 
     String[] original = {"a","bc","defe","dsa","bb"}; 

     List<String> originalValues = new ArrayList<String>(Arrays.asList(original)); 
     Map<Integer, List<String>> orderedValues = new HashMap<Integer, List<String>>(); 

     Iterator<String> it = originalValues.iterator(); 
     while (it.hasNext()) { 
      String currentElement = it.next(); 
      int length = currentElement.length(); 
      if(!orderedValues.containsKey(length)) { 
       orderedValues.put(length, new ArrayList<String>()); 
      } 
      orderedValues.get(length).add(currentElement); 
     } 
     System.out.println(orderedValues.values()); 
    } 
} 

あなたが代わりに地図の配列の配列を使用して、配列の位置にインデックスとして文字列のサイズを使用するように誘惑されるかもしれないが、その後、あなたはドン場合に注意する必要があります特定の長さの文字列を持っていません。元のリストに文字列がありますが、100文字しかない場合を想像してみてください。あなたは、この入力でそれを実行した場合

Collection<List<String>> output = input.stream() 
             .collect(Collectors.groupingBy(String::length)) 
             .values(); 

を:あなたは、それは、Java 8つのストリームに使用してそれを行うには簡単で、かなり効率的だ位置100

+0

Java 8では、 'get(length)'を 'computeIfAbsent(length、ArrayList :: new)'に置き換えて、 'if'文を削除することができます。 ---なぜ、単純な拡張forループの代わりにIterator whileループを使用していますか? ---これはループを 'for(String value:originalValues){orderedValues.computeIfAbsent(value.length()、ArrayList :: new)に減らします。 } ' – Andreas

+0

もっと普遍的な互換性を持たせようとしていましたが、Java 8で実装している場合は、このコメントのヒントが役立ちます。 – palako

2

で、アレイ内の99点の空の位置と1つの文字列を持っているでしょう

List<String> input = Arrays.asList("a", "bc", "defe", "dsa", "bb"); 

あなたはこの出力を取得します:非ストリームバージョンが同じことをするだろう

[[a], [bc, bb], [dsa], [defe]] 

をつまり、Map<K, List<V>>を作成します。ここで、Vは値のタイプです(例:あなたの場合はString)、Kはグループ化値のタイプです(例:の場合はInteger)。

あなた自身を実行すると(answer by palakoなどのように)、実行時にやや効率的になる可能性がありますが、それは決して重要ではありません。 Javaの8に滞在

、それはこのようになります:Javaの以前のバージョンについては

Map<Integer, List<String>> map = new HashMap<>(); 
for (String value : input) 
    map.computeIfAbsent(value.length(), ArrayList::new).add(value); 
Collection<List<String>> output = map.values(); 

、あなたがcomputeIfAbsent()を使用することはできませんので、:なし

Map<Integer, List<String>> map = new HashMap<Integer, List<String>>(); 
for (String value : input) { 
    Integer length = Integer.valueOf(value.length()); // box only once 
    List<String> list = map.get(length); 
    if (list == null) 
     map.put(length, list = new ArrayList<String>()); 
    list.add(value); 
} 
Collection<List<String>> output = map.values(); 
関連する問題