我有一个使用Java 8新流功能的示例代码(获取一系列int值1 .. 20,跳过前9个,然后取剩余10个,每个int值:减1并乘以2).
System.out.println(Arrays.toString(
IntStream.rangeClosed(1, 20).skip(9).limit(10).map((new IntUnaryOperator() {
@Override
public int applyAsInt(int operand) {
return operand - 1;
}
}).andThen(new IntUnaryOperator() {
@Override
public int applyAsInt(int operand) {
return operand * 2;
}
})).toArray()));
Run Code Online (Sandbox Code Playgroud)
输出如下:
[18, 20, 22, 24, 26, 28, 30, 32, 34, 36]
Run Code Online (Sandbox Code Playgroud)
现在我想用Lambda表达式替换匿名类.以下转换工作正常(第二个匿名类替换为i -> i * 2lambda表达式),我得到相同的输出:
System.out.println(Arrays.toString(
IntStream.rangeClosed(1, 20).skip(9).limit(10).map((new IntUnaryOperator() {
@Override
public int applyAsInt(int operand) {
return operand - 1;
}
}).andThen(i -> i * 2)).toArray()));
Run Code Online (Sandbox Code Playgroud)
但是,当我用lambda表达式替换第一个匿名类时:
System.out.println( …Run Code Online (Sandbox Code Playgroud) 我最近正在玩Java 8的新功能并观察到一个有趣的行为:
这没关系:
Class A { static void staticMethodInA() {println();} }
Class B extends A {}
B.staticMethodInA();
Run Code Online (Sandbox Code Playgroud)
这会导致以下错误:静态方法只能在包含接口类时调用.
interface A { static void staticMethodInA() {println();} }
Class B implements A {}
B.staticMethodInA(); // from here IntelliJ complaints..
Run Code Online (Sandbox Code Playgroud)
有人能告诉我为什么Java 8的设计者会选择以不同的方式对待上述两种情况吗?
我有一Record节课:
public class Record implements Comparable<Record>
{
private String myCategory1;
private int myCategory2;
private String myCategory3;
private String myCategory4;
private int myValue1;
private double myValue2;
public Record(String category1, int category2, String category3, String category4,
int value1, double value2)
{
myCategory1 = category1;
myCategory2 = category2;
myCategory3 = category3;
myCategory4 = category4;
myValue1 = value1;
myValue2 = value2;
}
// Getters here
}
Run Code Online (Sandbox Code Playgroud)
我创建了很多记录的大清单.仅第二和第五值,i / 10000并且i,将在后面使用的,由吸气剂getCategory2()和getValue1()分别.
List<Record> list = new ArrayList<>(); …Run Code Online (Sandbox Code Playgroud) 以下程序在Java 7和Eclipse Mars RC2 for Java 8中编译:
import java.util.List;
public class Test {
static final void a(Class<? extends List<?>> type) {
b(newList(type));
}
static final <T> List<T> b(List<T> list) {
return list;
}
static final <L extends List<?>> L newList(Class<L> type) {
try {
return type.newInstance();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
使用javac 1.8.0_45编译器,报告以下编译错误:
Test.java:6: error: method b in class Test cannot be applied to given types;
b(newList(type));
^
required: List<T>
found: CAP#1
reason: inference …Run Code Online (Sandbox Code Playgroud) 所以我有一组对象,它们的步长变量可以是1到4.
public class MyClass {
private Long step;
//other variables, getters, setters, etc.
}
Run Code Online (Sandbox Code Playgroud)
Collection<MyClass> myOjbects = /*get collection*/;
然后我想MyClass从集合中获得具有最大步长值的一个实例,所以我这样做:
final Optional<MyClass> objectWithMaxStep =
myObjects.stream().max(Comparator.comparing(MyClass::getStep));
Run Code Online (Sandbox Code Playgroud)
但是,在某些情况MyClass下,集合中将有多个实例,其步长等于4.
所以,我的问题是,如何确定返回哪个实例Optional,或者当流中的多个对象具有要比较的最大值时是否抛出异常?
该max()函数的Java 8文档未指定在这种情况下将发生的情况.
JDK是甲骨文的JDK 1.8u65,但问题是"低至"1.8u25.
这是完整的SSCCE:
public final class Foo
{
private interface X
{
default void x()
{
}
}
private enum E1
implements X
{
INSTANCE,
;
}
private enum E2
implements X
{
INSTANCE,
;
}
public static void main(final String... args)
{
Stream.of(E1.INSTANCE, E2.INSTANCE).forEach(X::x);
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码编译; 但它在运行时失败:
Exception in thread "main" java.lang.BootstrapMethodError: call site initialization exception
at java.lang.invoke.CallSite.makeSite(CallSite.java:341)
at java.lang.invoke.MethodHandleNatives.linkCallSiteImpl(MethodHandleNatives.java:307)
at java.lang.invoke.MethodHandleNatives.linkCallSite(MethodHandleNatives.java:297)
at com.github.fge.grappa.debugger.main.Foo.main(Foo.java:38)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: java.lang.invoke.LambdaConversionException: …Run Code Online (Sandbox Code Playgroud) 目前我正在使用java 8最新的android studio 2.1
这是我的build.gradle档案
android {
compileSdkVersion 22
buildToolsVersion "24rc3"
defaultConfig {
applicationId "com.name"
minSdkVersion 10
targetSdkVersion 19
jackOptions {
enabled true
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
.......
}
Run Code Online (Sandbox Code Playgroud)
我得到以下编译时错误,我不知道
错误:com.android.jack.frontend.FrontendCompilationException:无法在com.android.jack.Jack.run(Jack.java:472)的com.android.jack.Jack.buildSession(Jack.java:892)编译com.android.jack.api.v01.impl.Api01ConfigImpl $ Api01CompilationTaskImpl.run(Api01ConfigImpl.java:102)... 8更多警告:处理任务java.io.IOException时出现异常:com.android.jack.api.v01 .CompilationException:编译失败:oTT:compileDebugJavaWithJack FAILED错误:任务执行失败':oTT:compileDebugJavaWithJack'.
java.io.IOException:com.android.jack.api.v01.CompilationException:无法编译信息:BUILD FAILED
请您询问是否需要一些细节.
在这个问题中,用户@Holger提供了一个答案,显示了匿名类的不常见用法,我不知道.
该答案使用流,但这个问题不是关于流,因为这个匿名类型构造可以在其他上下文中使用,即:
String s = "Digging into Java's intricacies";
Optional.of(new Object() { String field = s; })
.map(anonymous -> anonymous.field) // anonymous implied type
.ifPresent(System.out::println);
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,这会编译并打印预期的输出.
注意:我很清楚,自古以来,可以构造一个匿名内部类并使用其成员,如下所示:
int result = new Object() { int incr(int i) {return i + 1; } }.incr(3);
System.out.println(result); // 4
Run Code Online (Sandbox Code Playgroud)
但是,这不是我在这里问的问题.我的情况不同,因为匿名类型是通过Optional方法链传播的.
现在,我可以想象这个功能的一个非常有用的用法......很多时候,我需要map在Stream管道上发出一些操作,同时保留原始元素,即假设我有一个人员列表:
public class Person {
Long id;
String name, lastName;
// getters, setters, hashCode, equals...
}
List<Person> people = ...;
Run Code Online (Sandbox Code Playgroud)
而且我需要Person在某些存储库中存储我的实例的JSON表示,为此我需要每个Person …
如何使用java流查找列表中的第一个匹配项或最后一个元素?
这意味着如果没有元素匹配条件,则返回最后一个元素.
例如:
OptionalInt i = IntStream.rangeClosed(1,5)
.filter(x-> x == 7)
.findFirst();
System.out.print(i.getAsInt());
Run Code Online (Sandbox Code Playgroud)
我该怎么办才能让它返回5;
我试图了解该reduce()方法如何在java-8中工作。
例如,我有以下代码:
public class App {
public static void main(String[] args) {
String[] arr = {"lorem", "ipsum", "sit", "amet"};
List<String> strs = Arrays.asList(arr);
int ijk = strs.stream().reduce(0,
(a, b) -> {
System.out.println("Accumulator, a = " + a + ", b = " + b);
return a + b.length();
},
(a, b) -> {
System.out.println("Combiner");
return a * b;
});
System.out.println(ijk);
}
}
Run Code Online (Sandbox Code Playgroud)
输出是这样的:
Accumulator, a = 0, b = lorem
Accumulator, a = 5, b = …Run Code Online (Sandbox Code Playgroud)