要按升序对其进行排序,我可以使用:
myMap.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
Run Code Online (Sandbox Code Playgroud)
我怎么能按降序排列呢?
我试图改变主意思考功能方式,并且最近面临一种情况,我需要从列表中获取元素,直到满足条件,我找不到一种简单的自然方式来实现这一点.显然我还在学习.
说我有这个清单:
List<String> tokens = Arrays.asList("pick me", "Pick me", "pick Me",
"PICK ME", "pick me and STOP", "pick me", "pick me and Stop", "pick me");
// In a non lambdas was you would do it like below
List<String> myTokens = new ArrayList<>();
for (String token : tokens) {
myTokens.add(token);
if (token.toUpperCase().endsWith("STOP")) {
break;
}
}
Run Code Online (Sandbox Code Playgroud)
提前感谢您的意见
注意:在发布之前,我读了一个谓词限制流,但我看不出如何能够根据我的问题调整答案.任何帮助将不胜感激.
Function接口的许多lambda都采用了这种形式
t -> {
// do something to t
return t;
}
Run Code Online (Sandbox Code Playgroud)
我经常这样做,所以我已经为此编写了一个方法.
static <T> Function<T, T> consumeThenReturn(Consumer<T> consumer) {
return t -> {
consumer.accept(t);
return t;
};
}
Run Code Online (Sandbox Code Playgroud)
这使我能够做到这样的非常好的事情:
IntStream.rangeClosed('A', 'Z')
.mapToObj(a -> (char) a)
.collect(Collectors.collectingAndThen(Collectors.toList(), consumeThenReturn(Collections::shuffle)))
.forEach(System.out::print);
Run Code Online (Sandbox Code Playgroud)
还有另一种方法可以在不依赖我自己的方法的情况下进行这样的转换吗?我错过的新API中有什么东西会让我的方法变得多余吗?
我遇到了一个场景,我想要小写HashMap的所有键(不要问为什么,我只需要这样做).HashMap有数百万条目.
起初,我以为我只是创建一个新的Map,迭代要小写的地图条目,并添加相应的值.这个任务应该每天只运行一次或类似的东西,所以我想我可以裸露这个.
Map<String, Long> lowerCaseMap = new HashMap<>(myMap.size());
for (Map.Entry<String, Long> entry : myMap.entrySet()) {
lowerCaseMap.put(entry.getKey().toLowerCase(), entry.getValue());
}
Run Code Online (Sandbox Code Playgroud)
但是,当我的服务器在这一次过载时,我正要复制Map时,会导致一些OutOfMemory错误.
现在我的问题是,如何以最小的内存占用来完成这项任务?
在小写后删除每个键 - 添加到新Map帮助?
我可以利用java8流来加快速度吗?(例如这样的事情)
Map<String, Long> lowerCaseMap = myMap.entrySet().parallelStream().collect(Collectors.toMap(entry -> entry.getKey().toLowerCase(), Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)
更新
似乎它是一个Collections.unmodifiableMap所以我没有选择
在小写之后移除每个键 - 添加到新地图
我试图使用java 8收集到ListMultiMap而不使用forEach操作.
如果我在Java 7中编写代码,它将是这样的:
ListMultimap<String, String> result = ArrayListMultimap.create();
for(State state: states) {
for(City city: state.getCities()) {
result.put(state.getName(), city.getName());
}
}
Run Code Online (Sandbox Code Playgroud)
我在网上找到了一个网站,讨论如何创建自己的收藏家,以便在这样的场景中使用.我将此实现用于收集器.然后我写了下面的代码:
ListMultimap<String, String> result = states
.stream()
.flatMap(state -> state.getCities().stream()
.map(city -> {
return new Pair(state, city);
}))
.map(pair -> {
return new Pair(pair.first().getName(), pair.second().getName()));
})
.collect(MultiMapCollectors.listMultimap(
Pair::first,
Pair::second
)
);
Run Code Online (Sandbox Code Playgroud)
但在收集级别,我只能传递一个参数,我似乎找到了传递两个参数的方法.按照网站上的例子,我明白要使用两者,我需要在多图中存储一对"对",如下所示:
ArrayListMultimap<String, Pair> testMap = testObjectList.stream().collect(MultiMapCollectors.listMultimap((Pair p) -> p.first().getName()));
Run Code Online (Sandbox Code Playgroud)
然而,这不是我想要的,我想使用状态的名称和使用java 8的收集器(并且没有forEach)的城市名称收集到ListMultimap中.
有人可以帮助我吗?谢谢!
我找到了以下代码片段:
Function<Integer, Predicate<Integer>> smallerThan = x -> y -> y < x;
List<Integer> l = Arrays.asList(5, 6, 7, 23, 4, 5645,
6, 1223, 44453, 60182, 2836, 23993, 1);
List<Integer> list2 = l.stream()
.filter(smallerThan.apply(l.get(0)))
.collect(Collectors.toList());
System.out.println(list2);
Run Code Online (Sandbox Code Playgroud)
作为输出我收到:
[4, 1]
Run Code Online (Sandbox Code Playgroud)
smallerThan考虑到我们只传递一个参数,本例中的函数如何工作smallerThan.apply(l.get(0))?
为什么会出错?我以为map可以回报任何价值.
var s = IntStream.rangeClosed(1, 5).map(String::valueOf).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
| 错误:| 不兼容的类型:方法引用中的错误返回类型| java.lang.String无法转换为int | var s = IntStream.rangeClosed(1,5).map(String :: valueOf).collect(Collectors.toList()); |
^ ^ -------------
Java 8具有java.util.stream.Stream和java.util.stream.IntStream类型.java.util.Arrays有一个方法
IntStream is = Arrays.stream(int[])
Run Code Online (Sandbox Code Playgroud)
但是没有这样的方法可以从byte [],short []或char []创建IntStream,将每个元素扩展为int.是否有一种从byte []创建IntStream的惯用/首选方法,所以我可以以函数方式操作字节数组?
我当然可以手动将byte []转换为int []并使用Arrays.stream(int []),或者使用IntStream.Builder:
public static IntStream stream(byte[] bytes) {
IntStream.Builder isb = IntStream.builder();
for (byte b: bytes)
isb.add((int) b);
return isb.build();
}
Run Code Online (Sandbox Code Playgroud)
但是由于复制了源代码,它们都不是很有用.
似乎没有一种简单的方法可以将InputStream(或者在本例中为ByteArrayInputStream)转换为IntStream,这对于在功能上处理InputStream非常有用.(明显遗漏?)
是否有更有效且不复制的功能方式?
在阅读了Java 8的java.util.stream.Intstream之后,我一直在用流替换一些传统的循环.不幸的是,在处理嵌套循环时遇到了一些性能问题.
正如预期的那样,以下代码在我的机器中运行大约47毫秒:
IntStream.range(0, 1000000000).forEach(i -> {});
Run Code Online (Sandbox Code Playgroud)
但是,嵌套另一个IntStream hyper会将执行时间膨胀到大约10,458 ms - 即:
IntStream.range(0, 1000000000).forEach(i -> {
IntStream.range(0, 1).forEach(j -> {});
});
Run Code Online (Sandbox Code Playgroud)
这是我的滥用案例,还是这个问题将来可以解决?
编辑:为了进行比较,以下代码使用传统的内部循环运行得更快(在1,801毫秒内).因此,即使考虑到优化,使用内部IntStream似乎也会有更多的开销?
final long[] random = {1};
IntStream.range(0, 1000000000).forEach(i -> {
for (int j = 0; j < 1; j++) {
random[0] += i;
}
});
Run Code Online (Sandbox Code Playgroud) 如何将转换Map<String, Double>到List<Pair<String, Double>>使用Java 8?
我写了这个实现,但效率不高
Map<String, Double> implicitDataSum = new ConcurrentHashMap<>();
//....
List<Pair<String, Double>> mostRelevantTitles = new ArrayList<>();
implicitDataSum.entrySet().stream().
.sorted(Comparator.comparing(e -> -e.getValue()))
.forEachOrdered(e -> mostRelevantTitles.add(new Pair<>(e.getKey(), e.getValue())));
return mostRelevantTitles;
Run Code Online (Sandbox Code Playgroud)
我知道它应该可以使用.collect(Collectors.someMethod()).但我不明白该怎么做.
java ×10
java-8 ×10
java-stream ×10
lambda ×3
arrays ×1
collectors ×1
guava ×1
hashmap ×1
performance ×1
sorting ×1