标签: java-8

Java 8,Lambda:用lambda替换Anonymous内部类

我有一个包含以下内容的类:

List roles = ldapTemplate.search(baseDn, replaceFilter, sc,
            new AttributesMapper() {
                public Object mapFromAttributes(Attributes attrs)
                        throws NamingException {
                    return attrs.get("cn").get();
                }
            });
Run Code Online (Sandbox Code Playgroud)

IntelliJ告诉我用lambda替换匿名内部类.所以我尝试过:

List roles = ldapTemplate.search(
    baseDn, replaceFilter, sc,
    (Attributes a)  -> { return a.get("cn").get(); };
);
Run Code Online (Sandbox Code Playgroud)

但是,我收到编译错误:

Error:(46, 50) java: incompatible types: inference variable T has incompatible bounds
    equality constraints: java.lang.String
    lower bounds: java.lang.Object
Run Code Online (Sandbox Code Playgroud)

我找不到解决这个问题的方法.你有什么想法?

java lambda java-8

31
推荐指数
3
解决办法
6万
查看次数

为什么Java 8不允许使用非公共默认方法?

我们来举个例子:

public interface Testerface {

    default public String example() {
        return "Hello";
    }

}

public class Tester implements Testerface {

    @Override
    public String example() {
        return Testerface.super.example() + " world!";
    }


}

public class Internet {

    public static void main(String[] args) {
        System.out.println(new Tester().example());
    }

}
Run Code Online (Sandbox Code Playgroud)

简单地说,这将打印出来Hello world!.但是说我正在使用返回值做其他事情Testerface#example,例如初始化数据文件并返回一个不应离开实现类的敏感内部值.为什么Java不允许在默认接口方法上使用访问修饰符?为什么它们不能被保护/私有并且可能被子类提升(类似于扩展父类的类如何为重写方法使用更可见的修饰符)?

一个常见的解决方案是转移到抽象类,但在我的特定情况下,我有一个枚举接口,所以这里不适用.我想它或者被忽略了,或者因为接口背后的原始想法是它们是可用方法的"契约",但我想我想要输入关于这个的内容.

我读过" 为什么"最终"在Java 8接口方法中不允许? ",其中指出:

默认方法的基本思想是:它是具有默认实现的接口方法,派生类可以提供更具体的实现

对我来说听起来就像可见性根本不会破坏那个方面.

与链接的问题一样,因为它看起来很难被关闭,所以在这个问题上会得到权威的答案,而不是基于意见的答案.

java java-8 default-method

31
推荐指数
1
解决办法
5624
查看次数

与Java 6相比,Java 8的GUI性能较差

在下面的Java 6中,代码按预期运行,但在Java 8中,它需要花费更多的时间.有趣的是,组件使用相同的方法setEnable()来启用和禁用组件,但禁用调用所需的时间比启用组件要长得多,几乎是后者的两倍.Java 8中的禁用时间比Java 1.6中的禁用时间长.问题是为什么会发生这种情况?这是Java 8的性能问题吗?

以下是Java 6的结果:

    Sun Microsystems Inc. 1.6.0_45
    Initializing GUI
    GUI initialized in 1105 ms
    Disabling
    Disabled in 687 ms
    Enabling
    Enabled in 375 ms
Run Code Online (Sandbox Code Playgroud)

以下是Java 8的结果:

    Oracle Corporation 1.8.0_25
    Initializing GUI
    GUI initialized in 604 ms
    Disabling
    Disabled in 6341 ms
    Enabling
    Enabled in 370 ms
Run Code Online (Sandbox Code Playgroud)

代码:

import java.awt.Component;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;

public class TestGUI extends JFrame implements ActionListener {

    private static final long …
Run Code Online (Sandbox Code Playgroud)

java performance user-interface swing java-8

31
推荐指数
2
解决办法
2708
查看次数

收集器的组合器功能是否可以用于顺序流?

示例程序:

public final class CollectorTest
{
    private CollectorTest()
    {
    }

    private static <T> BinaryOperator<T> nope()
    {
        return (t, u) -> { throw new UnsupportedOperationException("nope"); };
    }

    public static void main(final String... args)
    {
        final Collector<Integer, ?, List<Integer>> c
            = Collector.of(ArrayList::new, List::add, nope());

        IntStream.range(0, 10_000_000).boxed().collect(c);
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,为了简化这里的问题,没有最终的转换,因此生成的代码非常简单.

现在,IntStream.range()生成一个顺序流.我只是将结果打成Integers然后我的设计Collector将它们收集到一个List<Integer>.很简单.

无论我运行多少次这个示例程序,UnsupportedOperationException从不命中,这意味着我的虚拟组合器永远不会被调用.

我有点期待这个,但后来我已经误解了流,我不得不问这个问题......

可以在Collector当流的组合曾经被称为保证是连续的?

java java-8 java-stream

31
推荐指数
1
解决办法
3201
查看次数

当Java 8中的方法参数未经检查转换时,为什么会删除返回类型的泛型?

请考虑以下代码示例:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List list = new ArrayList<Integer>();
        String response = getProducer(list).get();
    }
    static Producer<String> getProducer(List<Integer> list) {
        return new Producer<String>();
    }
}
class Producer<T> {
    T get() {
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

在Java 7中编译时,它只会产生一个预期的警告getProducer(list):

警告:(7,39)java:需要取消选中转换:java.util.List<java.lang.Integer> 找到: java.util.List

但是,在Java 8中编译时,它会为response = getProducer(list).get()赋值生成以下错误:

错误:(7,48)java:不兼容的类型:java.lang.Object无法转换为java.lang.String

显然,返回的类型getProducer(list)不是Producer<String>,但是被删除Producer(这也通过IDE中的"提取变量"功能来确认).这非常令人费解,因为getProducer方法总会返回Producer<String>.

奇怪的是,它可以通过在调用getProducer方法时避免未经检查的转换来修复,或者通过:

  • 更改参数类型getProducer从 …

java generics java-8

31
推荐指数
2
解决办法
6151
查看次数

java 8流和并行流之间的区别

我使用java 8流和并行流编写代码以获得与自定义收集器相同的功能来执行聚合功能.当我看到CPU使用率时htop,它显示了用于"流"和"并行流"版本的所有CPU核心.因此,似乎在使用list.stream()时,它也使用所有CPU.这里,就多核使用而言,parallelStream()stream()之间的确切区别是什么.

java multithreading multicore java-8

31
推荐指数
1
解决办法
1万
查看次数

增强的循环编译适用于JDK 8但不适用于7

考虑下面的代码片段,我在进行一些重构之后,在检查为什么构建服务器报告了一个破坏的构建但在我的IDE中没问题时:

List<String> text;
...
for (String text : text) {...}
Run Code Online (Sandbox Code Playgroud)

因此,相同的名称用于for-each中的String和List.

这当然不是很明智,但是在重命名之前遵循我的好意,我看到上面的代码用JDK 8编译得很好,但是给出了JDK 7的以下错误:

  error: for-each not applicable to expression type
        for (String text : text) {
                           ^
  required: array or java.lang.Iterable
  found:    String
1 error
Run Code Online (Sandbox Code Playgroud)

我知道,变化在JDK中这方面的几个部分组成 - 但有人可以见识一下为什么会出现正是这种行为?


更新: 由于我得到了一些关于不同行为的评论,这里是一个完整的示例类:

import java.util.Arrays;
import java.util.List;

public class Strange {

    List<String> text = Arrays.asList("Max", "Alex", "Maria");

    public static void main(String[] args) {
        new Strange().doSomething("Alex");
    }

    public void doSomething(String name) {
        for (String text : text) {
            System.out.println(text.equals("Alex"));
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

这是编译过程和输出(Windows …

java foreach language-lawyer java-7 java-8

31
推荐指数
3
解决办法
2124
查看次数

用于在Java 8 Stream中进行排序的空安全日期比较器

我用这个来获得最新的项目.我怎样才能使这个为null安全并且最后(最旧)的空日期排序.createDt是一个joda LocalDate对象.

Optional<Item> latestItem = items.stream()
                             .sorted((e1, e2) -> e2.getCreateDt().compareTo(e1.getCreateDt()))
                             .findFirst();
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

31
推荐指数
2
解决办法
4万
查看次数

Java 8泛型:将消费者流量减少到单个消费者

我怎么能写组合的方法StreamConsumers到一个单一的Consumer使用Consumer.andThen(Consumer)

我的第一个版本是:

<T> Consumer<T> combine(Stream<Consumer<T>> consumers) {
    return consumers
            .filter(Objects::nonNull)
            .reduce(Consumer::andThen)
            .orElse(noOpConsumer());
}

<T> Consumer<T> noOpConsumer() {
    return value -> { /* do nothing */ };
}
Run Code Online (Sandbox Code Playgroud)

此版本使用JavaC和Eclipse编译.但它太具体了:Stream不能是a Stream<SpecialConsumer>,如果Consumers不是类型T而是超类型,则不能使用:

Stream<? extends Consumer<? super Foo>> consumers = ... ;
combine(consumers);
Run Code Online (Sandbox Code Playgroud)

这不会合理地编译.改进版将是:

<T> Consumer<T> combine(Stream<? extends Consumer<? super T>> consumers) {
    return consumers
            .filter(Objects::nonNull)
            .reduce(Consumer::andThen)
            .orElse(noOpConsumer());
}
Run Code Online (Sandbox Code Playgroud)

但Eclipse和JavaC都没有编译:
Eclipse(4.7.3a):

该类型Consumer未定义andThen(capture#7-of ? extends Consumer<? super …

java generics java-8 java-stream

31
推荐指数
1
解决办法
1498
查看次数

Java8 lambdas是否像匿名类一样维护对其封闭实例的引用?

我们知道匿名类维护对其封闭实例的引用,这可能导致Android上下文泄漏.

由于retrolambda backports中的lambda表达式来Java7,它可能是值得一试.

似乎 Java8 lambdas没有这个问题,但我找不到任何官方信息.

任何线索?

lambda java-8 retrolambda

30
推荐指数
2
解决办法
5216
查看次数