我试图弄清楚如何从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函数本身.有没有某种方法可以打破或强制整个方法返回?
我正在尝试显式使用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大师致敬!
从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
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) 我有一个方法,每次执行它时都会生成一个对象,我需要颠倒我获取它们的顺序.所以我认为这样做的自然方式就是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)顺序列表的正确方法吗?
是否可以将纯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) 您能否详细说明如何获得默认系统时区和给定时区的正确纪元时间(以毫秒为单位).
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午夜之间的差值(以毫秒为单位).
LocalDateTimeat 的输出GMT+3是相同的System.currentTimeMillis(),虽然System.currentTimeMillis()提到的文件UTC?LocalDateTimeat 的输出UTC不同System.currentTimeMillis(),虽然System.currentTimeMillis()提到的文件UTC?我对以下代码感到困惑
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表达式和方法引用之间存在一对一的关系,但显然并非如我的示例所示.
有人可以向我解释这里发生了什么吗?
据我了解,下面的代码应打印true,因为两者Stream并Iterator指向的第一个元素.
但是,当我运行以下代码时,它正在打印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)
不同行为的原因是什么?
我有一堆单元测试,包含如下代码:
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,它的工作原理.
到目前为止我尝试的事情:
更多细节:
forkCount=0通常有助于在这种情况下找出分叉VM崩溃的原因.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 ×10
java ×8
lambda ×3
java-stream ×2
bytecode ×1
datetime ×1
entryset ×1
interface ×1
iterator ×1
java-time ×1
jvm ×1
partitioning ×1
timezone ×1
windows-10 ×1