我有一个List<Foo>并且想要一个Multimap<String, Foo>我们Foo根据他们的getId()功能对其进行分组的地方.
我正在使用Java 8,它几乎可以做到:
List<Foo> foos = ...
Map<String, List<Foo>> foosById = foos.stream().collect(groupingBy(Foo::getId));
Run Code Online (Sandbox Code Playgroud)
但是,我有大量的代码需要一个,MultiMap<String, Foo>所以这并没有为我节省任何东西,我回到使用for循环来创建我的MultiMap.我错过了一个很好的"功能性"方式吗?
好的,所以方法重载是一个糟糕的事情.既然已经解决了这个问题,我们假设我实际上想要重载这样的方法:
static void run(Consumer<Integer> consumer) {
System.out.println("consumer");
}
static void run(Function<Integer, Integer> function) {
System.out.println("function");
}
Run Code Online (Sandbox Code Playgroud)
在Java 7中,我可以使用非模糊的匿名类作为参数轻松地调用它们:
run(new Consumer<Integer>() {
public void accept(Integer integer) {}
});
run(new Function<Integer, Integer>() {
public Integer apply(Integer o) { return 1; }
});
Run Code Online (Sandbox Code Playgroud)
现在在Java 8中,我当然想用lambda表达式调用这些方法,我可以!
// Consumer
run((Integer i) -> {});
// Function
run((Integer i) -> 1);
Run Code Online (Sandbox Code Playgroud)
既然编译器应该能够推断出来Integer,为什么我不离开Integer呢?
// Consumer
run(i -> {});
// Function
run(i -> 1);
Run Code Online (Sandbox Code Playgroud)
但这不编译.编译器(javac,jdk1.8.0_05)不喜欢这样:
Test.java:63: error: reference to run is …Run Code Online (Sandbox Code Playgroud) 我有两个java.util.Optional实例,我想得到一个Optional:
是否有直接的方法来做到这一点,即是否已经有一些API来做到这一点?
以下表达式会这样做,但我必须提到第一个可选的两次:
firstOptional.isPresent() ? firstOptional : secondOptional
Run Code Online (Sandbox Code Playgroud)
这正是com.google.common.base.Optional.or()如此,但Java 8的API中不存在该方法.
aioobe接受的答案列出了一些替代方法来克服这种遗漏OptionalAPI的权利,在这种情况下必须计算这样的值(这回答了我的问题).我现在选择在我的代码库中添加一个实用程序函数:
public static <T> Optional<T> or(Optional<T> a, Optional<T> b) {
if (a.isPresent())
return a;
else
return b;
}
Run Code Online (Sandbox Code Playgroud) 在Java8中运行以下流示例:
System.out.println(Stream
.of("a", "b", "c", "d", "e", "f")
.reduce("", (s1, s2) -> s1 + "/" + s2)
);
Run Code Online (Sandbox Code Playgroud)
收益率:
/a/b/c/d/e/f
Run Code Online (Sandbox Code Playgroud)
这是 - 当然 - 毫不奇怪.由于http://docs.oracle.com/javase/8/docs/api/index.html?overview-summary.html,流顺序执行还是并行执行无关紧要:
除了标识为显式非确定性的操作(例如findAny())之外,流是顺序执行还是并行执行不应更改计算结果.
AFAIK reduce()是确定性的并且(s1, s2) -> s1 + "/" + s2是关联的,因此添加parallel()应该产生相同的结果:
System.out.println(Stream
.of("a", "b", "c", "d", "e", "f")
.parallel()
.reduce("", (s1, s2) -> s1 + "/" + s2)
);
Run Code Online (Sandbox Code Playgroud)
但是我机器上的结果是:
/a//b//c//d//e//f
Run Code Online (Sandbox Code Playgroud)
这有什么不对?
BTW:使用(首选).collect(Collectors.joining("/"))而不是为顺序和并行执行reduce(...)产生相同的结果a/b/c/d/e/f.
JVM详细信息:
java.specification.version: 1.8
java.version: 1.8.0_31
java.vm.version: 25.31-b07
java.runtime.version: 1.8.0_31-b13
Run Code Online (Sandbox Code Playgroud) 让我们考虑一个hashmap
Map<Integer, List> id1 = new HashMap<Integer,List>();
Run Code Online (Sandbox Code Playgroud)
我在两个hashmap中都插入了一些值.
例如,
List<String> list1 = new ArrayList<String>();
list1.add("r1");
list1.add("r4");
List<String> list2 = new ArrayList<String>();
list2.add("r2");
list2.add("r5");
List<String> list3 = new ArrayList<String>();
list3.add("r3");
list3.add("r6");
id1.put(1,list1);
id1.put(2,list2);
id1.put(3,list3);
id1.put(10,list2);
id1.put(15,list3);
Run Code Online (Sandbox Code Playgroud)
Q1)现在我想对hashmap中的键应用过滤条件并检索相应的值(List).
例如:这里我的查询是key = 1,输出应该是'list1'
我写
id1.entrySet().stream().filter( e -> e.getKey() == 1);
Run Code Online (Sandbox Code Playgroud)
但我不知道如何检索列表作为此流操作的输出.
Q2)我想再次对hashmap中的键应用过滤条件并检索相应的列表列表.
例如:这里我的查询是key = 1%(即键可以是1,10,15),输出应该是'list1','list2','list3'(列表列表).
当我尝试通过以下任一方式运行 Zeppelin 时
bin/zeppelin.sh
Run Code Online (Sandbox Code Playgroud)
或者
bin/zeppelin-deamon.sh start
Run Code Online (Sandbox Code Playgroud)
我收到以下错误消息。
Unrecognized VM option 'MaxPermSize=512m'
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
Run Code Online (Sandbox Code Playgroud)
我的系统(Ubuntu 16.04)上安装了 Java 9。
$ java -version
openjdk version "9-internal"
OpenJDK Runtime Environment (build 9-internal+0-2016-04-14-195246.buildd.src)
OpenJDK 64-Bit Server VM (build 9-internal+0-2016-04-14-195246.buildd.src, mixed mode)
Run Code Online (Sandbox Code Playgroud) 我有一个Map<String, Double>,并希望将地图中的所有值乘以2,比方说,但是将空值保持为空.
我显然可以使用for循环来做到这一点,但是想知道是否有更清洁的方法呢?
Map<String, Double> someMap = someMapFunction();
Map<String, Double> adjustedMap = new Hashmap<>();
if (someMap != null) {
for (Map.Entry<String,Double> pair : someMap.entryset()) {
if (pair.getValue() == null) {
adjustedMap.put(pair.getKey(), pair.getValue());
} else {
adjustedMap.put(pair.getKey(), pair.getValue()*2)
}
}
}
Run Code Online (Sandbox Code Playgroud)
有时候返回的地图someMapFunction是一个不可变的地图,所以这不能用就地做Map.replaceAll.我无法想出一个更清洁的流解决方案.
这似乎是一个非常基本的问题,但我搜索得很高,并且发现几乎没有提到任何地方.所以,我会在这里问一下.
在GWT中支持Java 8的新语言结构的当前计划是什么?
此外,建议的Java 8库的哪个子集用于客户端仿真?Stream API?新的日期/时间API?
最后,关于这个重要主题的讨论在哪里进行?我敢肯定,我们中有许多人愿意参与并可能为此付出努力.
Java 8测试版现在已经存在了一段时间,并且有许多文章讨论了提议的API.它应该在今年晚些时候相关,所以似乎过去的时间至少要讨论如何以及何时将非常需要的语言功能引入GWT.
如果这个问题在其他地方得到解答,或者我错过了一些与之相关的重要信息,我很抱歉.即使已经回答,这也是获取此类信息链接的好地方.谢谢!
许多人声称,GoF设计模式的最大部分只是缺少一流功能的解决方法.既然Java即将获得lambda表达式,那些模式中的哪些将受到它们的影响?哪些可以大大简化或推广?那些基本上会保持不变?欢迎任何实际的例子.
跟我说,介绍有点啰嗦,但这是一个有趣的难题.
我有这个代码:
public class Testcase {
public static void main(String[] args){
EventQueue queue = new EventQueue();
queue.add(() -> System.out.println("case1"));
queue.add(() -> {
System.out.println("case2");
throw new IllegalArgumentException("case2-exception");});
queue.runNextTask();
queue.add(() -> System.out.println("case3-never-runs"));
}
private static class EventQueue {
private final Queue<Supplier<CompletionStage<Void>>> queue = new ConcurrentLinkedQueue<>();
public void add(Runnable task) {
queue.add(() -> CompletableFuture.runAsync(task));
}
public void add(Supplier<CompletionStage<Void>> task) {
queue.add(task);
}
public void runNextTask() {
Supplier<CompletionStage<Void>> task = queue.poll();
if (task == null)
return;
try {
task.get().
whenCompleteAsync((value, exception) -> runNextTask()).
exceptionally(exception …Run Code Online (Sandbox Code Playgroud) java-8 ×10
java ×8
lambda ×4
java-stream ×3
collectors ×1
guava ×1
gwt ×1
hashmap ×1
java-9 ×1
jls ×1
optional ×1
overloading ×1
ubuntu ×1