2016-04-08 11 views
17

を使用して、ブールに[]ブール値のオブジェクトを変換します[]私はこのようなコードに変換を行うことができますストリーム

Object[] array = (Object[]) message.get(key); 
boolean[] result = new boolean[array.length]; 
for (int i = 0; i < array.length; i++) { 
    result[i] = (boolean) array[i]; 
} 

しかし、私はそれは、Java 8を使用して同じ変換を行うことは可能だと思いましたストリーム。私は次のようなコードを作成します:

boolean[] = Arrays.stream(array) 
        .map(Boolean.class::cast) 
        .map(Boolean::booleanValue) 
        .toArray() 

しかし、このコードは動作しません。コンパイラの説明

incompatible types: java.lang.Object[] cannot be converted to boolean[] 

私はコードの問題点を理解しようとしています。私はmap(Boolean::booleanValue)toArrayで収集できるブール値のストリームを返すと思います。 map(Boolean::booleanValue)

map((Boolean value) -> (Boolean)value.booleanValue()); 

に展開されますので

+2

'Object []'と 'boolean []'はJavaの型であり、実際には 'Object [] = boolean []'は動作しないので動作しません。 – Jagger

+2

'.toArray()'は一般的なものなので、 'Object []'はあなたが達成できる最高のものです。 'boolean []'を返すように独自のコレクタを書くことができます。 –

+0

@SashaSalauyouしかし、型付き配列を返すために 'toArray(IntFunction ジェネレータ)'を使うことができます。私は例として答えを加えました。 –

答えて

15

ありませんが、これが理由です

map()に渡された関数がObject、ないbooleanを返すことがあるため、コンパイラによって挿入されたオートボクシングに注意してください) Java8ストリームには、一連の特殊クラス(IntStream,LongStream、およびDoubleStream)が含まれています。悲しいことに、booleanのための特別なストリームクラスはありません。あなたの代わりにリストを取得するという考えに反対していない場合は

8

、単にあなたの端末アクションとしてcollectを実行できます。

final List<Boolean> boolList = Arrays.stream(array) 
            .map(Boolean.class::cast) 
            .map(Boolean::booleanValue) 
            .collect(Collectors.toList()); 

ここで定義されたストリームは、あなたの場合Object[]を製造することができるだけですアレイに収集しようとします。リストを使用すると、少なくともあなたはそれを変換したいタイプを維持することができます。

+0

好奇心をそそられて、実際にやりたいと思ったらOPがリストをboolean配列に変換できないのですか? –

+2

@JeelShah:はい、しかし、 'boolean []'ではなく 'Boolean []'を得ることができます。 OPが 'boolean []'を望むなら、もう少し作業をしなければならないでしょう。 – Makoto

+0

ああ、大丈夫です。追加情報ありがとう! –

4

toArray(IntFunction<A[]> generator)がありますので、少なくともあなたが望むものに近いBoolean[]の最終結果を得ることができます。

Boolean[] boolArray = Arrays.stream(array) 
       .map(Boolean.class::cast) 
       .map(Boolean::booleanValue) 
       .toArray(Boolean[]::new); 
5

プリミティブ型の唯一の流れはIntStreamLongStreamDoubleStreamあります。特にBooleanStreamはありません。Stream<Boolean>boolean[]に変換する慣用的な方法はありません。頻繁にこの機能が必要な場合

あなたは次のようにユーティリティクラスを使用することができます。

public final class BooleanUtils { 

    private BooleanUtils() {} 

    public static boolean[] listToArray(List<Boolean> list) { 
     int length = list.size(); 
     boolean[] arr = new boolean[length]; 
     for (int i = 0; i < length; i++) 
      arr[i] = list.get(i); 
     return arr; 
    } 

    public static final Collector<Boolean, ?, boolean[]> TO_BOOLEAN_ARRAY 
     = Collectors.collectingAndThen(Collectors.toList(), BooleanUtils::listToArray); 
} 

その後、Stream<Boolean>与え、あなたが行うことができるようになります:

boolean[] arr = stream.collect(BooleanUtils.TO_BOOLEAN_ARRAY); 
2

Javaのプリミティブ型が上がりませんしたがって、Booleanbooleanに直接変換することはできません(Java 1.5では言語にautoboxing and unboxingが追加され、プリミティブ型のラッパータイプの配列では動作しません)。あなたは、サードパーティのライブラリを使用して好きではない場合

boolean[] result = Arrays.stream(array) 
         .collect(MoreCollectors.toBooleanArray(obj -> (boolean)obj)); 

:私の自由StreamExライブラリーでは、プリミティブboolean型配列を作成しますコレクタtoBooleanArrayがありますしかし、あなたはIntStream.range(int, int)

よう
boolean[] result = new boolean[array.length]; 
IntStream.range(0, array.length).forEach(x -> result[x] = (boolean) array[x]); 
2

を使用することができます

public static <T> Collector<T, ?, boolean[]> toBooleanArray(Predicate<? super T> predicate) { 
    class Acc { 
     BitSet bs = new BitSet(); 
     int count = 0; 
    } 
    return Collector.of(Acc::new, (acc, t) -> acc.bs.set(acc.count++, predicate.test(t)), 
      (acc1, acc2) -> { 
       acc2.bs.stream().forEach(i -> acc1.bs.set(i + acc1.count)); 
       acc1.count += acc2.count; 
       return acc1; 
      }, acc -> { 
       boolean[] res = new boolean[acc.count]; 
       acc.bs.stream().forEach(i -> res[i] = true); 
       return res; 
      }); 
} 

これは、順次ストリームと並列ストリームでうまく動作し、終了します。メモリに優しい。

関連する問題