标签: java-8

从lambda表达式中的方法返回值

我试图弄清楚如何从lambda表达式返回一个方法值:

public int findMissingNumber(Collection<Integer> ints) {
    Single<Integer> start = new Single<>(1);
    ints.stream().mapToInt(Integer::valueOf).parallel().forEach(i -> {
        if (i != start.setValue(start.getValue() + 1)) {
            //return here
        }
    });
    return -1;
}
Run Code Online (Sandbox Code Playgroud)

但是,似乎return在lambda表达式中使用关键字将显式返回lambda函数本身.有没有某种方法可以打破或强制整个方法返回?

java lambda java-8

19
推荐指数
2
解决办法
3万
查看次数

显式使用LambdaMetafactory

我正在尝试显式使用LambdaMetafactory.metafactory,我无法理解为什么它仅适用于Runnable功能接口.例如,此代码执行预期的操作(它打印"hello world"):

public class MetafactoryTest {

    public static void main(String[] args) throws Throwable {

        MethodHandles.Lookup caller = MethodHandles.lookup();
        MethodType methodType = MethodType.methodType(void.class);
        MethodType invokedType = MethodType.methodType(Runnable.class);
        CallSite site = LambdaMetafactory.metafactory(caller, 
                                                      "run", 
                                                      invokedType, 
                                                      methodType, 
                                                      caller.findStatic(MetafactoryTest.class, "print", methodType), 
                                                      methodType);
        MethodHandle factory = site.getTarget();
        Runnable r = (Runnable) factory.invoke();
        r.run();
    }

    private static void print() {
        System.out.println("hello world"); 
    }    
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用不同的功能界面时会出现问题,例如Supplier.以下代码不起作用:

public class MetafactoryTest {

    public static void main(String[] args) throws Throwable {

        MethodHandles.Lookup caller = MethodHandles.lookup();
        MethodType methodType = MethodType.methodType(String.class);
        MethodType invokedType …
Run Code Online (Sandbox Code Playgroud)

java lambda metaprogramming java-8

19
推荐指数
1
解决办法
6161
查看次数

从默认接口方法记录

向所有Java大师致敬!

从Java8开始,我们可以在接口中使用默认实现(yay!).但是,如果要从默认方法进行日志记录,则会出现问题.

我有一种感觉,每次我想在默认方法中记录某些内容时调用.getLogger()是不明智的.

是的,可以在接口中定义静态变量 - 但这对接口来说不是一个好的做法+它暴露了记录器(必须是公共的).

我现在的解决方案:

interface WithTimeout<Action> {

    default void onTimeout(Action timedOutAction) {
        LogHolder.LOGGER.info("Action {} time out ignored.", timedOutAction);
    }

    static final class LogHolder {
        private static final Logger LOGGER = getLogger(WithTimeout.class);
    }
}
Run Code Online (Sandbox Code Playgroud)

LogHolder对所有人来说仍然是可见的,因为它没有提供任何方法,并且它应该是接口内部的.

你们有没有人知道更好的解决方案?:)

编辑:我使用Logback支持的SLF4J

java interface java-8

19
推荐指数
1
解决办法
7473
查看次数

为什么lambda转换需要生成静态方法?

Lambda转换是一个两步过程,一个是:将lambda放入同一个类中的静态方法中.

public class Main {
    public static void main(String[] args) {
        Runnable r = () -> System.out.println("Hello");
        System.out.println(Arrays.asList(Main.class.getDeclaredMethods()));
    }
}
Run Code Online (Sandbox Code Playgroud)

[ private static void Main.lambda $ main $ 0(),public static void Main.main(java.lang.String [])]

:生成实现功能接口的类.

System.out.println("A class has been generated: " + r.getClass());
System.out.println("That implements a Functional Interface: " + Arrays.asList(r.getClass().getInterfaces()));
Run Code Online (Sandbox Code Playgroud)

已生成一个类:类Main $$ Lambda $ 1/149928006

这实现了一个功能接口:[interface java.lang.Runnable]

问题:这种静态方法需要什么?为什么不能将lambda主体直接放入接口方法?就像是:

class Main$$Lambda$1 {
    public void run() {
        /* Lambda body here */
    }
}
Run Code Online (Sandbox Code Playgroud)

java lambda jvm bytecode java-8

19
推荐指数
2
解决办法
1612
查看次数

使用Java 8集合流API进行堆栈

我有一个方法,每次执行它时都会生成一个对象,我需要颠倒我获取它们的顺序.所以我认为这样做的自然方式就是Stack,因为它是LIFO.

但是,Java Stack似乎不能很好地与新的Java 8流API一起使用.

如果我这样做:

   Stack<String> stack = new Stack<String>();
   stack.push("A");
   stack.push("B");
   stack.push("C");

   List<String> list = stack.stream().collect(Collectors.toList());
   System.out.println("Collected: " + list);
Run Code Online (Sandbox Code Playgroud)

我得到的输出是:

Collected: [A, B, C]
Run Code Online (Sandbox Code Playgroud)

为什么不以预期的LIFO顺序将它们输出到流中?这是将所有项目从堆栈清除到右(LIFO)顺序列表的正确方法吗?

java java-8 java-stream java-collections-api

19
推荐指数
1
解决办法
9267
查看次数

Java 8分区列表

是否可以将纯Jdk8中的List分区为相等的块(子列表).

我知道可以使用Guava Lists类,但是我们可以使用纯Jdk吗?我不想在我的项目中添加新的jar,仅用于一个用例.

解决方案:

tagir-valeev提出了迄今为止最好的解决方案:

我还发现了其他三种可能性,但它们只适用于少数情况:

1.Collectors.partitioningBy()将列表拆分为2个子列表 - 如下所示:

intList.stream().collect(Collectors.partitioningBy(s -> s > 6));
    List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
Run Code Online (Sandbox Code Playgroud)

2.Collectors.groupingBy()将我们的列表拆分为多个分区:

 Map<Integer, List<Integer>> groups = 
      intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3));
    List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());
Run Code Online (Sandbox Code Playgroud)

3.分离器分离:

List<Integer> intList = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6, 0, 7, 8);

    int[] indexes = 
      Stream.of(IntStream.of(-1), IntStream.range(0, intList.size())
      .filter(i -> intList.get(i) == 0), IntStream.of(intList.size()))
      .flatMapToInt(s -> s).toArray();
    List<List<Integer>> subSets = 
      IntStream.range(0, indexes.length - 1)
               .mapToObj(i …
Run Code Online (Sandbox Code Playgroud)

java partitioning java-8

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

JSR 310 :: System.currentTimeMillis()vs Instant.toEpochMilli():: TimeZone

您能否详细说明如何获得默认系统时区和给定时区的正确纪元时间(以毫秒为单位).

特定

1. TimeZone:GMT + 3

2.以下代码段:

import java.time.*;

public class Main {        
    public static void main(String[] args) {
        System.out.println(LocalDateTime
            .now()
            .atZone(ZoneOffset.UTC)
            .toInstant()
            .toEpochMilli()
        );
        System.out.println(LocalDateTime
            .now()
            .atZone(ZoneOffset.of("+3"))
            .toInstant()
            .toEpochMilli()
        );
        System.out.println(System.currentTimeMillis());
    }
}
Run Code Online (Sandbox Code Playgroud)

3.输出:

1444158955508
1444148155508
1444148155508
Run Code Online (Sandbox Code Playgroud)

4.用于System.currentTimeMillis()的 JavaDoc,它告诉返回的值将是当前时间与1970年1月1日UTC午夜之间的差值(以毫秒为单位).

所以为什么

  1. LocalDateTimeat 的输出GMT+3是相同的System.currentTimeMillis(),虽然System.currentTimeMillis()提到的文件UTC
  2. LocalDateTimeat 的输出UTC不同System.currentTimeMillis(),虽然System.currentTimeMillis()提到的文件UTC

java timezone datetime java-8 java-time

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

为什么返回类型的Java方法引用与Consumer接口匹配?

我对以下代码感到困惑

class LambdaTest {
    public static void main(String[] args) {
        Consumer<String>         lambda1 = s -> {};
        Function<String, String> lambda2 = s -> s;

        Consumer<String>         lambda3 = LambdaTest::consume; // but s -> s doesn't work!
        Function<String, String> lambda4 = LambdaTest::consume;
    }

    static String consume(String s) { return s;}
}
Run Code Online (Sandbox Code Playgroud)

我原本期望lambda3的赋值失败,因为我的consume方法与Consumer Interface中的accept方法不匹配 - 返回类型不同,String与void.

此外,我一直认为Lambda表达式和方法引用之间存在一对一的关系,但显然并非如我的示例所示.

有人可以向我解释这里发生了什么吗?

java-8

19
推荐指数
2
解决办法
3056
查看次数

在Map的entrySet中流与Iterator

据我了解,下面的代码应打印true,因为两者StreamIterator指向的第一个元素.

但是,当我运行以下代码时,它正在打印false:

final HashMap<String, String> map = new HashMap<>();
map.put("A", "B");
final Set<Map.Entry<String, String>> set = Collections.unmodifiableMap(map).entrySet();
Map.Entry<String, String> entry1 = set.iterator().next();
Map.Entry<String, String> entry2 = set.stream().findFirst().get();
System.out.println(entry1 == entry2);
Run Code Online (Sandbox Code Playgroud)

不同行为的原因是什么?

java iterator java-8 java-stream entryset

19
推荐指数
2
解决办法
1686
查看次数

在带有Java 8.191的Windows 10上,File.exists()有时会出错

我有一堆单元测试,包含如下代码:

File file = new File("src/main/java/com/pany/Foo.java");
assertTrue("Missing file: " + file.getAbsolutePath(), file.exists());
Run Code Online (Sandbox Code Playgroud)

使用Maven Surefire运行它时,此测试突然失败-DforkCount=0.随着-DforkCount=1,它的工作原理.

到目前为止我尝试的事情:

  • 该文件确实存在.Windows资源管理器,命令行(复制和粘贴),文本编辑器,Cygwin都可以找到它并显示内容.这就是为什么我认为这不是一个许可问题.
  • 它不会被单元测试或其他任何东西修改.Git在过去两个月没有显示任何修改.
  • 我检查了文件系统,它很干净.
  • 我尝试过其他版本的Java 8,即8u171和8u181.同样的问题.
  • 我从Cygwin和命令提示符下运行Maven.结果相同.
  • 重启:-)没效果:-(

更多细节:

  • 当我看到这个问题时,我开始看到"分叉的虚拟机在没有正确说再见的情况下终止.虚拟机崩溃或System.exit被调用?" 在其他项目中.这就是为什么我尝试forkCount=0通常有助于在这种情况下找出分叉VM崩溃的原因.
  • 这种情况最近已经开始,可能是在2018年10月更新的Windows 10之前.在此之前,这些版本坚固了大约三年.我认为我的机器在2017年末转为Windows 10.
  • 我正在使用Maven 3.6并且因为一个重要的错误而无法轻松尝试旧版本.我确实看到上面的VM崩溃了Maven 3.5.2.
  • 它始终是失败的相同文件(因此它是稳定的).

ulimit (来自Cygwin)说:

$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 8
stack size              (kbytes, -s) 2032
cpu time               (seconds, -t) unlimited …
Run Code Online (Sandbox Code Playgroud)

java-8 windows-10

19
推荐指数
1
解决办法
456
查看次数