假设我想要重构以下方法
protected Stream<T> parseFile(File file, Consumer<File> cleanup) {
try {
return parser.parse(file); // returns a Stream<T>
} catch (XmlParseException e) { // child of RuntimeException
throw new CustomRuntimeException(e);
} finally {
if (file != null) {
cleanup.accept(file);
}
}
throw new IllegalStateException("Should not happen");
}
Run Code Online (Sandbox Code Playgroud)
此方法的目的是充当代理,在包装异常中的流重新抛出上附加错误处理CustomRuntimeException.因此,当我们稍后在流程中使用它时,我不必在任何地方处理这些异常,而只是处理它们CustomRuntimeException.
上游,我使用的方法如下
try {
Stream<T> stream = parseFile(someFile);
stream.map(t -> ...);
catch (CustomRuntimeException e) {
// do some stuff
}
Run Code Online (Sandbox Code Playgroud)
这就是parser.parse方法的样子
public Stream<T> parse() {
// ValueIterator<T> implements Iterator<T>, AutoCloseable
XmlRootParser.ValueIterator<T> …Run Code Online (Sandbox Code Playgroud) List<Rate> rateList =
guestList.stream()
.map(guest -> buildRate(ageRate, guestRate, guest))
.collect(Collectors.toList());
class Rate {
protected int index;
protected AgeRate ageRate;
protected GuestRate guestRate;
protected int age;
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,可以通过guestList内部buildRate方法的索引。我在构建时还需要传递索引,Rate但无法通过来获取索引Stream。
我想增加index每次迭代的值1.很容易实现for-loop.变量image是一个数组ImageView.
这是我的for-loop.
for (Map.Entry<String, Item> entry : map.entrySet()) {
image[index].setImage(entry.getValue().getImage());
index++;
}
Run Code Online (Sandbox Code Playgroud)
为了练习Stream,我尝试将其重写为Stream:
map.entrySet().stream()
.forEach(e -> item[index++].setImage(e.getValue().getImage()));
Run Code Online (Sandbox Code Playgroud)
导致我错误的原因:
错误:从lambda表达式引用的局部变量必须是final或者有效的final
如何重写Stream递增index要使用的变量?
考虑这个片段:
@ParameterizedTest
@ValueSource(strings = {"a", "b", "c"})
void test(final String line) {
// code here
}
Run Code Online (Sandbox Code Playgroud)
这将是一个实际测试,但为了简单起见,假设其目的只是打印以下内容:
Line 1: processed "a" successfully.
Line 2: processed "b" successfully.
Line 3: failed to process "c".
Run Code Online (Sandbox Code Playgroud)
换句话说,我希望测试值的索引可以在测试中访问。根据我的发现,{index}可以在测试之外使用它来正确命名。
所以我有一些使用Java 8流的代码,它可以工作.它完全符合我的需要,而且它清晰可读(函数式编程很少见).在子例程的末尾,代码在自定义对类型的List上运行:
// All names Hungarian-Notation-ized for SO reading
class AFooAndABarWalkIntoABar
{
public int foo_int;
public BarClass bar_object;
....
}
List<AFooAndABarWalkIntoABar> results = ....;
Run Code Online (Sandbox Code Playgroud)
这里的数据必须作为数组传递给程序的其他部分,因此它们会被复制出来:
// extract either a foo or a bar from each "foo-and-bar" (fab)
int[] foo_array = results.stream()
.mapToInt (fab -> fab.foo_int)
.toArray();
BarClass[] bar_array = results.stream()
.map (fab -> fab.bar_object)
.toArray(BarClass[]::new);
Run Code Online (Sandbox Code Playgroud)
并做了.现在每个阵列都可以做到.
除了......在列表上的循环两次困扰我的灵魂.如果我们需要跟踪更多信息,他们可能会添加第三个字段,然后必须进行第三次传递以将3元组转换为三个数组,等等.所以我在努力尝试一次性完成.
分配数据结构是微不足道的,但维护消费者使用的索引似乎很可怕:
int[] foo_array = new int[results.size()];
BarClass[] bar_array = new BarClass[results.size()];
// the trick is providing a stateful iterator across the …Run Code Online (Sandbox Code Playgroud) 我想对任何不成功的响应都有failfast行为,如果一切都成功,那么我将返回上一个成功的响应,如下面的代码所示.
for(int i=0;i<input.size(); i++){
Data data = service.getData(input.get(i));
if(data.isSuccessful() && i==input.size()-1){
return data;
}else if(!data.isSuccessful()){
return data;
}else{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我试图用流替换上面提到的代码,但是到目前为止还没能做到.主要问题是我无法模仿java8流代码中的i(索引)变量行为.
resp = input.stream().map((input)->{service.getData()}).filter(
(resp)->{
if(!resp.isSuccessful())
return true;
else if(resp.isSuccessful() && last resp)//if somehow I figure out last element
return true;
else
return false;}).findFirst();
Run Code Online (Sandbox Code Playgroud) 是否可以IntStream使用索引迭代int数组?
试着这样做:
ByteBuf buf = ...;
int[] anArray = ...;
IntStream.of(anArray).forEach(...); // get index so I can do "anArray[index] = buf.x"
Run Code Online (Sandbox Code Playgroud) 我知道如何通过谓词查找列表的第一个元素: Java 8通过谓词查找第一个元素
有没有一种简单的方法来获取该元素的索引?
编辑:链接的问题确实提供了答案,但是由于其表达方式,我在搜索时找不到它。因此,我宁愿保留这个问题。
是否有一种方便的Java8流API方式从List<T> to Map<T, (index)>以下示例进行转换:
List<Character> charList = "ABCDE".chars().mapToObj(e->(char)e).collect(Collectors.toList());
Map<Character, Integer> map = new HashMap<>();
for (int i = 0; i < charList.size(); i++) {
map.put(charList.get(i), i);
}
Run Code Online (Sandbox Code Playgroud)
映射= {A = 0,B = 1,C = 2,D = 3,E = 4}
很想知道是否有更优雅的方法试图在Java 8中找到字符串中奇数位置的数字总和.
这是我目前的职能
/**
* Explode string into char array, get sum of ASCII values at odd positions and divide by 10 to convert
* to the integer value from that character
* @param ccNumber string
* @return int sum
*/
int calculateSumOfOddDigits(final String ccNumber) {
final char[] digits = ccNumber.toCharArray();
return (digits[0] + digits[2] + digits[4] + digits[6] + digits[8] + digits[10] + digits[12] + digits[14]) / 10;
}
Run Code Online (Sandbox Code Playgroud)
还不熟悉Streams和Java 8,想想也许你可以这样做:
ccNumber.chars().mapToObj(x -> (char) x {
..add odd position …Run Code Online (Sandbox Code Playgroud)