在Java8流中,我可以修改/更新其中的对象吗?例如.List<User> users:
users.stream().forEach(u -> u.setProperty("value"))
Run Code Online (Sandbox Code Playgroud) 就像几乎所有人一样,我仍然在学习新的Java 8 Streams API的复杂性(并且非常喜欢它们).我有一个关于流的使用的问题.我将提供一个简化的例子.
Java Streams允许我们使用a Collection,并使用stream()它上面的方法来接收所有元素的流.在这,有许多有用的方法,比如filter(),map()和forEach(),这让我们对内容的使用拉姆达操作.
我的代码看起来像这样(简化):
set.stream().filter(item -> item.qualify())
.map(item -> (Qualifier)item).forEach(item -> item.operate());
set.removeIf(item -> item.qualify());
Run Code Online (Sandbox Code Playgroud)
我们的想法是获取集合中所有项目的映射,这些项目匹配某个限定符,然后通过它们进行操作.操作后,它们不再用于其他目的,应从原始组中移除.代码运作良好,但我无法摆脱这样的感觉,即有一个操作Stream可以在一行中为我做这件事.
如果它在Javadocs中,我可能会忽略它.
是否有人更熟悉API会看到类似的东西?
我有点困惑之间Stream#findAny(),并Stream#findFirst()在的 Stream在Java API 8.
我理解的是,两者都将从流中返回第一个匹配的元素,例如,当与过滤器一起使用时?
那么,为什么两种方法相同的任务呢?我错过了什么吗?
我经常遇到同样的问题.我需要计算一个lambda的运行,以便在lambda之外使用.例如:
myStream.stream().filter(...).forEach(item->{ ... ; runCount++);
System.out.println("The lambda ran "+runCount+"times");
Run Code Online (Sandbox Code Playgroud)
问题是runCount需要是final,所以它不能是int.它不能是一个整数,因为那是不可变的.我可以使它成为类级变量(即一个字段),但我只需要在这个代码块中.我知道有各种各样的方式,我只是好奇你最喜欢的解决方案是什么?您使用AtomicInteger或数组引用还是其他方式?
据我所知,List<Double>使用Java 8流总结的方法是这样的:
List<Double> vals = . . . ;
double sum = vals.stream().mapToDouble(Double::doubleValue).sum();
Run Code Online (Sandbox Code Playgroud)
对我来说,这mapToDouble(Double::doubleValue)似乎是一种狡猾 - 只是那种lambdas和溪流应该免除的样板"仪式".
最佳实践告诉我们更喜欢List实例而不是数组,但是对于这种求和,数组似乎更清晰:
double[] vals = . . . ;
double sum = Arrays.stream(vals).sum();
Run Code Online (Sandbox Code Playgroud)
当然,人们可以这样做:
List<Double> vals = . . . ;
double sum = vals.stream().reduce(0.0, (i,j) -> i+j);
Run Code Online (Sandbox Code Playgroud)
但那reduce(....)比这长得多sum().
我知道这与流需要围绕Java的非对象原语进行改造的方式有关,但是,我在这里遗漏了一些东西吗?有没有办法挤压自动装箱以缩短它?或者这仅仅是当前最先进的技术?
以下是答案的摘要.虽然我在这里有一个摘要,但我敦促读者自己仔细阅读答案.
@dasblinkenlight解释说,由于Java历史上的进一步决策,特别是在实现泛型的方式以及它们与非对象原语的关系中,因此总是需要某种拆箱.他指出,理论上编译器可以直接进行拆箱并允许使用简短的代码,但这还没有实现.
@Holger展示了一个非常接近我所询问的表现力的解决方案:
double sum = vals.stream().reduce(0.0, Double::sum);
Run Code Online (Sandbox Code Playgroud)
我不知道新的静态Double.sum()方法.添加1.8,似乎是出于我描述的目的.我也发现了Double.min()和Double.max().展望未来,我肯定会使用这个成语来进行类似的操作List<Double>.
鉴于元素的列表,我想用一个给定的属性来获取元素,并从列表中删除.我找到的最佳解决方案是:
ProducerDTO p = producersProcedureActive
.stream()
.filter(producer -> producer.getPod().equals(pod))
.findFirst()
.get();
producersProcedureActive.remove(p);
Run Code Online (Sandbox Code Playgroud)
是否可以在lambda表达式中组合get和remove?
也许这很简单,但我实际上是Java 8功能的菜鸟,不知道如何实现这一点.我有这个简单的行包含以下文本:
"钥匙,名字"
我想将该行转换为String数组,用逗号(,)分隔每个值,但是,我还希望在返回最终数组之前修剪每个字段,因此我执行了以下操作:
Arrays.stream(line.split(",")).map(String::trim).toArray();
Run Code Online (Sandbox Code Playgroud)
但是,这会返回Object []数组而不是String []数组.经过进一步检查,我可以确认内容实际上是String实例,但数组本身是Object元素.让我来说明一下,这是调试器对返回对象的说法:
Object[]:
0 = (String) "Key"
1 = (String) "Name"
Run Code Online (Sandbox Code Playgroud)
据我所知,问题出在map调用的返回类型中,但是如何让它返回一个String []数组呢?
我有两个(或更多)Map<String, Integer>对象.我想将它们与Java 8 Stream API合并,使公共键的值应该是值的最大值.
@Test
public void test14() throws Exception {
Map<String, Integer> m1 = ImmutableMap.of("a", 2, "b", 3);
Map<String, Integer> m2 = ImmutableMap.of("a", 3, "c", 4);
List<Map<String, Integer>> list = newArrayList(m1, m2);
Map<String, Integer> mx = list.stream()... // TODO
Map<String, Integer> expected = ImmutableMap.of("a", 3, "b", 3, "c", 4);
assertEquals(expected, mx);
}
Run Code Online (Sandbox Code Playgroud)
如何将此测试方法设为绿色?
我已经打了collect,并Collectors有一阵子没有任何成功.
(ImmutableMap和newArrayList来自谷歌番石榴).
我正在使用Java 8 lambdas并希望Collectors toMap用来返回一个SortedMap.我能想出的最好的是调用下面Collectors toMap用假设法mergeFunction和mapSupplier等于TreeMap::new.
public static <T, K, U, M extends Map<K, U>>
Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier) {
BiConsumer<M, T> accumulator = (map, element) -> map.merge(keyMapper.apply(element),
valueMapper.apply(element), mergeFunction);
return new CollectorImpl<>(mapSupplier, accumulator, mapMerger(mergeFunction), CH_ID);
}
Run Code Online (Sandbox Code Playgroud)
我不想传递合并函数,正如我想要throwingMerger()的那样,与基本toMap实现相同,如下所示:
public static <T, K, U>
Collector<T, ?, Map<K, U>> toMap(Function<? …Run Code Online (Sandbox Code Playgroud) 我在Java中有以下搜索代码:
return getTableViewController().getMe().getColumns().stream().filter($->Database.equalsColumnName($.getId(), columnId)).findFirst().get();
Run Code Online (Sandbox Code Playgroud)
我希望按名称找到列并返回第一个找到的列.
我知道有一个案例,什么都没找到,应该处理,但如何?
这就是它所要的咒骂:
'Optional.get()' without 'isPresent()' check
Run Code Online (Sandbox Code Playgroud)
?
怎么修?null如果没有找到,我希望回来.
UPDATE
好吧,好吧,我只是没有意识到,那会findFirst()回来Optional.
java ×10
java-8 ×10
java-stream ×10
lambda ×3
arrays ×1
collections ×1
collectors ×1
filtering ×1
merge ×1
optional ×1