使用流将booleans的Object []转换为boolean []

时间:2016-04-08 19:12:00

标签: java arrays java-stream

我可以使用以下代码进行转换:

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收集的布尔值流。

6 个答案:

答案 0 :(得分:16)

不,因为map(Boolean::booleanValue)扩展为

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

(注意编译器插入的自动装箱,因为传递给map()的函数必须返回Object,而不是boolean

这就是为什么Java8流包含一大堆专门的类(IntStreamLongStreamDoubleStream)。遗憾的是,boolean没有专门的流类。

答案 1 :(得分:8)

如果您不反对获取列表的想法,您只需执行final Pattern p = Pattern.compile("[0-9]{8}[#](FRI|SAT|SUN)[\r]"); final Matcher m = p.matcher("09042012#SUN\r" + "09022012#FRI\r" + "09032012#SAT\r"); while (m.find()) { final String result = m.group(); System.out.println(result); } 作为终端操作:

collect

如果您尝试将其收集到数组中,此处定义的流只能生成final List<Boolean> boolList = Arrays.stream(array) .map(Boolean.class::cast) .map(Boolean::booleanValue) .collect(Collectors.toList()); 。使用列表至少可以让您维护要将其转换为的类型。

答案 2 :(得分:6)

唯一的原始类型流是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);

答案 3 :(得分:4)

我认为值得注意的是,toArray(IntFunction<A[]> generator)至少会让你的Boolean[]的最终结果更接近你想要的结果。

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

答案 4 :(得分:2)

Java原语类型不是引用类型,因此您不能直接将Boolean转换为booleanautoboxing and unboxing已添加到Java 1.5中的语言中并且不起作用与原始类型的包装类型数组)。但是,您可以使用IntStream.range(int, int)之类的

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

答案 5 :(得分:2)

在我的免费StreamEx库中有一个收集器toBooleanArray,它创建了一个原始的布尔数组:

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

如果您不喜欢使用第三方库,您可以自己实施这样的收集器:

{{1}}

它适用于顺序和并行流,并且非常适合内存。