我有一个类别为SomeObject
的列表
List<SomeObject> list = //fill list;
我只需要一个数组,其列表的所有项目的属性为bytes
,且总数为chunk
byte[] allBytes
->包含list.get(0).getChunk(), ..,list.get(list.size() - 1).getChunk();
public class BuildArrayBytes {
public static void main(String[] args) {
List<SomeObject> list = new ArrayList<>();
//fill list;
byte[] allBytes = buildArray(list);
}
public static byte[] buildArray(List<SomeObject> list) {
int totalSize = list.stream()
.map(item -> item.getChunk())
.collect(Collectors.summingInt(chunk -> chunk.length));
byte[] allBytes = new byte[totalSize];
int position = 0;
for (int i = 0; i < list.size(); i++) {
byte[] bytes = list.get(i).getChunk();
System.arraycopy(bytes, 0, allBytes, position, bytes.length);
position += bytes.length;
}
return allBytes;
}
class SomeObject {
private byte[] chunk;
public SomeObject(byte[] chunk) {
this.chunk = chunk;
}
public byte[] getChunk() {
return chunk;
}
}
}
使用ByteArrayOutputStream
public static byte[] buildArray(List<SomeObject> list) {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
list.stream().forEach(item -> {
try {
byteArrayOutputStream.write(item.getChunk());
} catch (IOException ex) {
ex.printStackTrace();
}
});
return byteArrayOutputStream.toByteArray();
}
它似乎仍然不雅:(
是否可以使用Lambda替换buildArray
方法?
答案 0 :(得分:1)
如果您使用list.stream().forEach()
,请考虑使用list.forEach()
。如果list.forEach()
看起来很糟,请考虑使用普通的for
循环,该循环适用于这种带有副作用的处理(例如ByteArrayOutputStream::write
)。
如果您坚持使用Stream API的方式(不要与“ lambda”混淆,后者是匿名类实现的一个表达式和快捷方式),请执行以下操作:
list.stream()
.map(SomeObject::getChunk)
.forEach(byteArrayOutputStream::write);
由于ByteArrayOutputStream
本身不会引发异常,因此SomeObject::getChunk
会引发异常。因此,要么在流中处理它(不好):
list.stream()
.map(i -> try { return i.getChunk(); }
catch (IOException ex) { /* handle the exception */ })
.forEach(byteArrayOutputStream::write);
或在将异常传递到流之前对其进行处理:
list.stream()
.map(BuildArrayBytes.safeChunk())
.filter(Objects::nonNull) // Be careful! Filter out invalid (null) chunks
.forEach(byteArrayOutputStream::write);
...
private static Function<SomeObject, Integer> safeChunk() {
return i -> {
try {
return i.getChunk();
} catch (IOException e) {
/* handle properly */
}
return null;
};
}