Tag: java 8

如何正确确定一个对象是一个lambda?

我看到lambda的类是isSynthetic() && !isLocalOrAnonymousClass() ,但我认为对于代理类也是如此。 当然,我可以检查getDeclaredMethods().length == 1并将regexp应用于类名。 不过,我想知道是否有一个更优雅和健壮的选项,以找出一个给定的对象是否是lambda。

Java 8方法引用未处理的exception

我正在使用Java 8开发项目,发现一个我无法理解的情况。 我有这样的代码: void deleteEntity(Node node) throws SomeException { for (ChildNode child: node.getChildren()) { deleteChild(child); } } void deleteChild(Object child) throws SomeException { //some code } 此代码工作正常,但我可以用方法引用重写它: void deleteEntity(Node node) throws SomeException { node.getChildren().forEach(this::deleteChild); } 而且这段代码不能编译, Incompatible thrown types *SomeException* in method reference给出错误Incompatible thrown types *SomeException* in method reference 。 还IDEA给了我错误unhandled exception 。 那么,我的问题是为什么? 为什么代码为每个循环编译,不用lambda编译?

Java中默认关键字的用途是什么?

Java中的接口与类相似,但接口的主体只能包含抽象方法和final字段(常量)。 最近我看到一个问题,看起来像这样 interface AnInterface { public default void myMethod() { System.out.println("D"); } } 根据接口定义, 只允许抽象方法 。 为什么它允许我编译上面的代码? 什么是default关键字? 另一方面,当我试图写下面的代码,然后说modifier default not allowed here default class MyClass{ } 代替 class MyClass { } 任何人都可以告诉我的default关键字的目的? 是否只允许在一个界面内? 它与default (没有访问修饰符)有什么不同?

org.apache.tomcat.util.bcel.classfile.ClassFormatException:常量池中的无效字节标记:15

我正在从Tomcat 7移植一个Web应用程序到另一个Tomcat 7,但与Java 8的服务器。 Tomcat成功启动,但在日志catalina.out我得到: org.apache.tomcat.util.bcel.classfile.ClassFormatException: Invalid byte tag in constant pool: 15 at org.apache.tomcat.util.bcel.classfile.Constant.readConstant(Constant.java:131) at org.apache.tomcat.util.bcel.classfile.ConstantPool.<init>(ConstantPool.java:60) at org.apache.tomcat.util.bcel.classfile.ClassParser.readConstantPool(ClassParser.java:209) at org.apache.tomcat.util.bcel.classfile.ClassParser.parse(ClassParser.java:119) at org.apache.catalina.startup.ContextConfig.processAnnotationsStream(ContextConfig.java:2049) at org.apache.catalina.startup.ContextConfig.processAnnotationsJar(ContextConfig.java:1931) at org.apache.catalina.startup.ContextConfig.processAnnotationsUrl(ContextConfig.java:1899) at org.apache.catalina.startup.ContextConfig.processAnnotations(ContextConfig.java:1885) at org.apache.catalina.startup.ContextConfig.webConfig(ContextConfig.java:1281) at org.apache.catalina.startup.ContextConfig.configureStart(ContextConfig.java:855) at org.apache.catalina.startup.ContextConfig.lifecycleEvent(ContextConfig.java:346) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:119) at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:90) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5172) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:618) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1100) at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1618) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) […]

将两个Map <String,Integer>与Java 8 Stream API合并

我有两个(或更多) 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); […]

Java 8 Collectors.toMap SortedMap

我正在使用Java 8 lambdaexpression式,并希望使用Collectors toMap来返回一个SortedMap 。 我能想到的最好的办法是用一个mapSupplier于TreeMap::new的dummy mergeFunction和mapSupplier调用下面的Collectors toMap方法。 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); […]

为什么这个通用代码在java 8中编译?

我偶然发现了一段代码,让我想知道为什么编译成功: public class Main { public static void main(String[] args) { String s = newList(); // why does this line compile? System.out.println(s); } private static <T extends List<Integer>> T newList() { return (T) new ArrayList<Integer>(); } } 有趣的是,如果我用<T extends ArrayList<Integer>>修改newList方法的签名,它就不再工作了。 注释和响应之后更新:如果将genericstypes从方法移动到类中,代码将不再编译: public class SomeClass<T extends List<Integer>> { public void main(String[] args) { String s = […]

将Java未来转化为CompletableFuture

Java 8引入了CompletableFuture ,这是一个可组合的Future的新实现(包括一堆thenXxx方法)。 我想独占地使用它,但是我想使用的许多库只返回不可组合的Future实例。 有一种方法来包装在一个CompleteableFuture里面的一个返回的Future实例,这样我就可以编写它了吗?

mapToDouble()对于使用Java 8stream汇总List <Double>真的是必需的吗?

据我所知,使用Java 8stream来对List<Double>进行求和的方式是这样的: List<Double> vals = . . . ; double sum = vals.stream().mapToDouble(Double::doubleValue).sum(); 对于我来说, mapToDouble(Double::doubleValue)似乎是一种蹩脚的 – 就是那种lambda和stream应该放弃的样板“仪式”。 最佳实践告诉我们要优先使用List实例而不是数组,而对于这种总结,数组看起来更清晰: double[] vals = . . . ; double sum = Arrays.stream(vals).sum(); 当然,可以这样做: List<Double> vals = . . . ; double sum = vals.stream().reduce(0.0, (i,j) -> i+j); 但是reduce(….)比sum()长得多。 我知道这与Java的非对象原语需要改进的方式有关,但是我仍然在这里错过了一些东西吗? 有办法挤压自动装箱,使这个更短吗? 或者这仅仅是当前的艺术状态? 更新 – 答案摘要 以下是对以下答案的摘要。 虽然我在这里有一个总结,但我敦促读者自己仔细阅读答案。 @dasblinkenlight解释说,由于在Java历史上进一步的决定,特别是generics被实现的方式以及它们与非对象原语的关系,总是需要某种拆箱。 他指出,编译器理论上可以直观的拆箱,并允许简单的代码,但是这还没有实现。 […]

Java 8 lambda和匿名内部类之间的性能差异

在Java 8之前,可以通过使用匿名内部类来实现lambdafunction。 例如: interface Lambda { void doStuff(); } // … public void doWithCallback(Lambda callback) { // … callback.doStuff(); } // … doWithCallback(new Lambda { public void doStuff() { // … } }); 在性能方面,仍然使用这种方法和使用新的Java 8 lambdaexpression式有什么区别?