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代码在操作数堆栈异常上发送 java.lang.VerifyError:Bad类型
public class TestJavaCodes {
int parentData = 0;
public void init() {
A ob = new B();
}
public static void main(String[] args) {
TestJavaCodes testJavaCodes = new TestJavaCodes();
testJavaCodes.init();
}
public static class A {
public A(MyLambdaFunc lambdaFunc) {
}
}
public class B extends A {
public B() {
super((data1, type) -> {
parentData = 1;
});
}
}
@FunctionalInterface
public static interface MyLambdaFunc {
public void onData(String data, int type);
} …Run Code Online (Sandbox Code Playgroud) 我想排序seq1升序和seq2降序所以我这样做:
list = list.stream().sorted(comparing(AClass::getSeq1).thenComparing(
AClass::getSeq2).reversed()).collect(toList());
Run Code Online (Sandbox Code Playgroud)
但结果出来了,因为seq1和seq2都按降序排序.
我可以这样做以使seq1升序和seq2降序:
sorted(comparing(AClass::getSeq1)
.reversed().thenComparing(AClass::getSeq2).reversed()
Run Code Online (Sandbox Code Playgroud)
这是真正的正确方法吗?
假设我要删除我的所有非字母String.
String s = "abc-de3-2fg";
Run Code Online (Sandbox Code Playgroud)
我可以用a IntStream来做到这一点:
s.stream().filter(ch -> Character.isLetter(ch)). // But then what?
Run Code Online (Sandbox Code Playgroud)
为了将此流转换回String实例,我该怎么办?
另外,为什么我不能将a String视为类型的对象流Character?
String s = "abc-de3-2fg";
// Yields a Stream of char[], therefore doesn't compile
Stream<Character> stream = Stream.of(s.toCharArray());
// Yields a stream with one member - s, which is a String object. Doesn't compile
Stream<Character> stream = Stream.of(s);
Run Code Online (Sandbox Code Playgroud)
根据javadoc,其Stream创建签名如下:
Stream.of(T ...值)
我能想到的唯一(糟糕的)方式是:
String s = "abc-de3-2fg";
Stream<Character> stream = Stream.of(s.charAt(0), s.charAt(1), s.charAt(2), ...)
Run Code Online (Sandbox Code Playgroud)
当然,这还不够好......我错过了什么?
在Java 8上读了一下,我得到了这篇博文,解释了一些关于流和减少它们的内容,以及什么时候可以缩短缩减.在底部它表明:
注意在
findFirst或者findAny我们只需要与谓词匹配的第一个值(虽然findAny不能保证返回第一个).但是如果流没有排序,那么我们期望findFirst表现得像findAny.的操作allMatch,noneMatch并anyMatch可能不短路流,因为在所有可能需要评估所有的值,以确定操作者是否是true或false.因此,使用这些的无限流可能不会终止.
我得到了这个findFirst或者findAny可能会缩短减少量,因为一旦你找到了一个元素,你就不需要再进一步处理了.
但为什么这不可能allMatch,noneMatch并且anyMatch?因为allMatch,如果找到与谓词不匹配的一个,则可以停止处理.同样没有.而且anyMatch尤其是没有道理给我,因为它几乎等于findAny(除了返回什么)?
说这三个可能不会短路,因为它可能需要评估所有的值,也可以说findFirst/Any.
我缺少一些根本区别吗?我真的不明白发生了什么事吗?
并行流可能会产生与Java 8中的串行流不同的结果吗?根据我的信息,并行流与串行流相同,除了分成多个子流.这是一个速度问题.完成对元素的所有操作,并在最后组合子流的结果.最后,在我看来,对于并行和串行流,操作的结果应该是相同的.所以我的问题是,这段代码可能会给我一个不同的结果吗?如果有可能,为什么会发生?
int[] i = {1, 2, 5, 10, 9, 7, 25, 24, 26, 34, 21, 23, 23, 25, 27, 852, 654, 25, 58};
Double serial = Arrays.stream(i).filter(si -> {
return si > 5;
}).mapToDouble(Double::new).map(NewClass::add).reduce(Math::atan2).getAsDouble();
Double parallel = Arrays.stream(i).filter(si -> {
return si > 5;
}).parallel().mapToDouble(Double::new).map(NewClass::add).reduce(Math::atan2).getAsDouble();
System.out.println("serial: " + serial);
System.out.println("parallel: " + parallel);
Run Code Online (Sandbox Code Playgroud)
public static double add(double i) {
return i + 0.005;
}
Run Code Online (Sandbox Code Playgroud)
结果是:
serial: 3.6971567726175894E-23
parallel: 0.779264049587662
Run Code Online (Sandbox Code Playgroud) 通常,并不十分清楚并行流如何将输入分成块以及块连接的顺序.有没有办法可视化任何流源的整个过程,以更好地了解正在发生的事情?假设我创建了一个这样的流:
Stream<Integer> stream = IntStream.range(0, 100).boxed().parallel();
Run Code Online (Sandbox Code Playgroud)
我想看到一些树状的结构:
[0..99]
_____/ \_____
| |
[0..49] [50..99]
__/ \__ __/ \__
| | | |
[0..24] [25..49] [50..74] [75..99]
Run Code Online (Sandbox Code Playgroud)
这意味着整个输入范围[0..99]被拆分为范围,[0..49]而[50..99]范围又进一步分裂.当然这样的图应该反映Stream API的实际工作,所以如果我用这样的流执行一些实际操作,则应该以相同的方式执行拆分.
使用Java 8 lambdas,有效创建新的List<T>给定的List<K>密钥和"a "的"最佳"方法是Map<K,V>什么?在这种情况下,您将获得一些List可能的Map键,并且应该生成一个List<T>where T,这是基于Vmap值类型的某些方面构造的某种类型.
我已经探索了一些并且感到不舒服声称一种方式比另一种方式更好(可能有一个例外 - 参见代码).我将澄清"最佳"作为代码清晰度和运行时效率的组合.这些是我想出来的.我相信有人可以做得更好,这是这个问题的一个方面.我不喜欢filter大多数方面,因为它意味着需要创建中间结构和多次传递名称List.现在,我选择了例6 - 一个简单的'ol循环.(注意:代码注释中有一些神秘的想法,特别是"需要外部引用......"这意味着从lambda外部.)
public class Java8Mapping {
private final Map<String,Wongo> nameToWongoMap = new HashMap<>();
public Java8Mapping(){
List<String> names = Arrays.asList("abbey","normal","hans","delbrook");
List<String> types = Arrays.asList("crazy","boring","shocking","dead");
for(int i=0; i<names.size(); i++){
nameToWongoMap.put(names.get(i),new Wongo(names.get(i),types.get(i)));
}
}
public static void main(String[] args) {
System.out.println("in main");
Java8Mapping j = new Java8Mapping();
List<String> testNames = Arrays.asList("abbey", "froderick","igor");
System.out.println(j.getBongosExample1(testNames).stream().map(Bongo::toString).collect(Collectors.joining(", "))); …Run Code Online (Sandbox Code Playgroud) 我希望能够像这样使用Stream :: flatMap
public static List<String> duplicate(String s) {
List<String> l = new ArrayList<String>();
l.add(s);
l.add(s);
return l;
}
listOfStrings.stream().flatMap(str -> duplicate(str)).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
但是我得到以下编译器错误
Test.java:25:错误:不兼容的类型:无法推断类型变量R listOfStrings.stream().flatMap(str - > duplicate(str)).collect(Collectors.toList());
(参数不匹配; lambda表达式中的错误返回类型List无法转换为Stream)
其中R,T是类型变量:R extends方法flatMap中声明的Object(Function>)T extends Interface在Interface Stream中声明的Object
在scala我可以做我认为相同的事情
scala> List(1,2,3).flatMap(duplicate(_))
res0: List[Int] = List(1, 1, 2, 2, 3, 3)
Run Code Online (Sandbox Code Playgroud)
为什么这不是java中flatMap的有效用法?
我喜欢番石榴,我会继续使用番石榴.但是,在有意义的地方,我尝试使用Java 8中的"新东西" .
"问题"
让我们说我想加入url属性String.在Guava我会这样做:
Map<String, String> attributes = new HashMap<>();
attributes.put("a", "1");
attributes.put("b", "2");
attributes.put("c", "3");
// Guava way
String result = Joiner.on("&").withKeyValueSeparator("=").join(attributes);
Run Code Online (Sandbox Code Playgroud)
凡result为a=1&b=2&c=3.
题
在Java 8(没有任何第三方库)中,最优雅的方法是什么?
java ×10
java-8 ×10
java-stream ×8
lambda ×4
bytecode ×1
comparator ×1
dictionary ×1
flatmap ×1
jvm ×1
sorting ×1
string ×1