前段时间,Oracle决定在Java 8中添加Closures是个好主意.我想知道与Scala相比,那里的设计问题是如何解决的,Scala从第一天就开始关闭.
援引未解决的问题,从javac.info:
方法句柄可以用于函数类型吗? 如何做到这一点并不明显.一个问题是Method Handles重新定义类型参数,但是以一种干扰函数子类型的方式.
我们可以摆脱"throws"类型参数的显式声明吗? 只要声明的边界是一个经过检查的异常类型,这个想法就是使用析取类型推断.这不是严格向后兼容的,但它不太可能破坏真正的现有代码.然而,由于语法模糊,我们可能无法摆脱类型参数中的"抛出".
在旧式循环索引变量上禁止@Shared
处理像Comparator这样定义多个方法的接口,除了其中一个接口之外的所有接口都将由继承自Object的方法实现."使用单一方法的接口"的定义应仅计算不会由Object中的方法实现的方法,并且如果实现其中一个方法将全部实现它们,则应将多个方法计为一个方法.主要是,这需要更精确地说明接口只有一个抽象方法的含义.
指定从函数类型到接口的映射:名称,参数等.我们应该完全指定从函数类型到系统生成的接口的映射.
类型推断.需要增加类型推断的规则以适应异常类型参数的推断.同样,闭包转换使用的子类型关系也应该反映出来.
Elined异常类型参数有助于改进异常透明度. 也许使得省略的异常类型参数意味着绑定.这样可以通过添加新的通用异常参数来改进没有异常类型参数的现有通用接口,例如java.util.concurrent.Callable.
函数类型的类文字是如何形成的? 是#void().class?如果是这样,如果擦除对象类型,它是如何工作的?它是#?(?).class?
系统类加载器应动态生成函数类型接口. 与函数类型对应的接口应该由引导类加载器按需生成,因此它们可以在所有用户代码之间共享.对于原型,我们可能有javac生成这些接口,因此原型生成的代码可以在库存(JDK5-6)VM上运行.
每次对lambda表达式的求值必须产生一个新的对象吗? 希望不是.例如,如果lambda没有从封闭范围捕获变量,则可以静态分配.类似地,在其他情况下,如果lambda不捕获循环内声明的任何变量,则lambda可以移出内部循环.因此,如果规范不承诺关于lambda表达式的结果的引用标识,那么最好是这样的,因此这样的优化可以由编译器完成.
据我所知2.,6.和7.在Scala中不是问题,因为Scala不使用Checked Exceptions作为某种类似Java的"影子类型系统".
剩下的呢?
这样做的时候
Stream.of(1, 32, 12, 15, 23).map(Integer::toString);
Run Code Online (Sandbox Code Playgroud)
我得到一个模糊的类型错误.可以理解的是,编译器无法分辨我的意思toString(int)或toString()来自Integer.
当不使用方法引用时,我可能已经通过显式转换或者写出泛型的长手程来解决这个问题,但是如何让编译器知道我的意思呢?我可以使用什么语法(如果有的话)来明确?
我想了一下并提出了一个有趣的问题,假设我们有一个配置(输入)文件:
x -> x + 1
x -> x * 2
x -> x * x
x -> -x
Run Code Online (Sandbox Code Playgroud)
此外,我们有一个Integers 列表:
List<Integer> list = new ArrayList<>();
list.addAll(Arrays.toList(1, 2, 3, 4, 5));
Run Code Online (Sandbox Code Playgroud)
有没有办法将Strings(x -> x + 1等)转换为Object代表lambda表达式的s?然后可以用作:
Object lambda = getLambdaFromString("x -> x + 1");
if (lambda.getClass().equals(IntFunction.class) {
list.stream().forEach()
.mapToInt(x -> x)
.map(x -> ((IntFunction)lambda).applyAsInt(x))
.forEach(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)
我怎么写这样的方法getLambdaFromString?
Object lambda到仅捕获lambda的其他东西?我试图使用Spring和Java 8 JDK运行一个简单的JUnit测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
@WebAppConfiguration
public class UserServicesTest{
@Test
public void testJava8() {
Set<String> strings = new HashSet<>();
strings.add("a");
strings.add("b");
strings.add("c");
strings.stream().filter(a -> a.equals("a")).forEach(p -> p.toString());
}
Run Code Online (Sandbox Code Playgroud)
我在启动时遇到了这个运行时错误:
org.aspectj.apache.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 18
at org.aspectj.apache.bcel.classfile.Constant.readConstant(Constant.java:133)
at org.aspectj.apache.bcel.classfile.ConstantPool.<init>(ConstantPool.java:45)
at org.aspectj.apache.bcel.classfile.ClassParser.readConstantPool(ClassParser.java:186)
at org.aspectj.apache.bcel.classfile.ClassParser.parse(ClassParser.java:131)
at org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository.loadJavaClass(NonCachingClassLoaderRepository.java:262)
at org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository.loadClass(NonCachingClassLoaderRepository.java:242)
at org.aspectj.apache.bcel.util.NonCachingClassLoaderRepository.loadClass(NonCachingClassLoaderRepository.java:249)
at org.aspectj.weaver.reflect.Java15AnnotationFinder.getAnnotations(Java15AnnotationFinder.java:202)
at org.aspectj.weaver.reflect.ReflectionBasedResolvedMemberImpl.unpackAnnotations(ReflectionBasedResolvedMemberImpl.java:211)
at org.aspectj.weaver.reflect.ReflectionBasedResolvedMemberImpl.hasAnnotation(ReflectionBasedResolvedMemberImpl.java:163)
at org.aspectj.weaver.patterns.ExactAnnotationTypePattern.matches(ExactAnnotationTypePattern.java:109)
at org.aspectj.weaver.patterns.ExactAnnotationTypePattern.matches(ExactAnnotationTypePattern.java:96)
at org.aspectj.weaver.patterns.AnnotationPointcut.matchInternal(AnnotationPointcut.java:156)
at org.aspectj.weaver.patterns.Pointcut.match(Pointcut.java:137)
at org.aspectj.weaver.internal.tools.PointcutExpressionImpl.getShadowMatch(PointcutExpressionImpl.java:239)
at org.aspectj.weaver.internal.tools.PointcutExpressionImpl.matchesExecution(PointcutExpressionImpl.java:105)
at org.aspectj.weaver.internal.tools.PointcutExpressionImpl.matchesMethodExecution(PointcutExpressionImpl.java:96)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.getShadowMatch(AspectJExpressionPointcut.java:404)
at org.springframework.aop.aspectj.AspectJExpressionPointcut.matches(AspectJExpressionPointcut.java:271)
at org.springframework.aop.support.AopUtils.canApply(AopUtils.java:224)
at …Run Code Online (Sandbox Code Playgroud) 有没有更好的方法来计算Java8的出现次数
int[] monthCounter = new int[12];
persons.stream().forEach(person -> monthCounter[person.getBirthday().getMonthValue() - 1]++);
Run Code Online (Sandbox Code Playgroud) 我对列表操作的了解来自脚本语言.所以在Java中,我找到了一些奇怪的东西,以便找到具有特定名称的cookie.
List<Cookie> cookies = Arrays.asList(request.getCookies());
String auth = cookies.stream()
.filter(c -> c.getName().equals("auth"))
.map(Cookie::getValue);
Run Code Online (Sandbox Code Playgroud)
在map方法上,IntelliJ向我展示了"循环推理".
Java编译器错误:(52,25)java:不兼容类型:没有类型变量的实例R存在,以便java.util.stream.Stream符合java.lang.String
我遇到过Java 8 CompletableFuture.exceptionally方法的奇怪行为.如果我执行此代码,它可以正常工作并打印java.lang.RuntimeException
CompletableFuture<String> future = new CompletableFuture<>();
future.completeExceptionally(new RuntimeException());
future.exceptionally(e -> {
System.out.println(e.getClass());
return null;
});
Run Code Online (Sandbox Code Playgroud)
但是如果我在将来的处理中添加另一个步骤,就像thenApply异常类型更改为java.util.concurrent.CompletionException包含在内部的原始异常.
CompletableFuture<String> future = new CompletableFuture<>();
future.completeExceptionally(new RuntimeException());
future.thenApply(v-> v).exceptionally(e -> {
System.out.println(e);
return null;
});
Run Code Online (Sandbox Code Playgroud)
有什么理由说这应该发生吗?在我看来,这是非常令人惊讶的.
据我所知,Java 8 JLS表达式(1/0)被认为是一个常量表达式,但是当我尝试使用OpenJDK 8编译以下程序时出现错误
public class Switch {
public static void main(String[] args) {
switch(42) {
case (1/0):
return;
default:
return;
}
}
}
Run Code Online (Sandbox Code Playgroud)
错误说(1/0)不是一个常量表达式
Switch.java:4: error: constant expression required
case (1/0):
^
1 error
Run Code Online (Sandbox Code Playgroud)
我错过了什么吗?或者它是OpenJDK 8中的错误?
是否有一种将Integer数组转换为int数组的奇特方法?(我不想迭代每个元素;我正在寻找一种优雅而快速的方法来编写它)
我正在使用另一种方式
scaleTests.add(Arrays.stream(data).boxed().toArray(Double[]::new));
我正在寻找单线但无法找到的东西.
目标是:
int[] valuesPrimitives = <somehow cast> Integer[] valuesWrapper
Run Code Online (Sandbox Code Playgroud) 我无法编译它,甚至可以链接谓词lambdas?
Arrays.asList("1","2","3").stream().filter( (e -> e=="1" ).or(e-> e=="2") ).count();
Run Code Online (Sandbox Code Playgroud)
或者唯一的方法是显式创建一个谓词,然后像这样组合:
Predicate<String> isOne= e -> e=="1";
Arrays.asList("1","2","3").stream().filter( isOne.or(e -> e=="2") ).count();
Run Code Online (Sandbox Code Playgroud)
或者是否有更多"功能优雅"的方式来实现同样的目标?