请考虑以下Java 8代码段.
public static void main(String[] args) {
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Consumer<Integer> consumer = x -> System.out.print(x);
integers.forEach(consumer);
}
Run Code Online (Sandbox Code Playgroud)
什么是Consumer<Integer> consumer = x -> System.out.print(x)编译到?
我知道Lambdas不是作为匿名内部类实现的.然而Consumer<Integer>,接口因此x -> System.out.print(x)必须产生某种对象,但不清楚生成什么样的对象.
Java 8中是否有一些新类型的对象来表示lambda表达式?
更新这里是程序与eclipse java 8编译器一起编译的反编译程序,下面的输出是在打开类文件时来自eclipse.
看起来lambda表达式在包含lambda表达式的类上变成了一个静态方法 private static synthetic void lambda$0(java.lang.Integer x);
// Compiled from Example.java (version 1.8 : 52.0, super bit)
public class Example {
// Method descriptor #6 ()V
// Stack: 1, Locals: 1
public Example();
0 aload_0 …Run Code Online (Sandbox Code Playgroud) 在java.timeJDK 8中的JSR-310 API中,计算将日期添加到日期的结果的规则是什么.特别是,当您将1个月添加到1月31日这样的日期时会发生什么?
LocalDate initial = LocalDate.of(2012, 1, 31); // 31st January 2012
LocalDate result = initial.plusMonths(1);
// what is the result?
Run Code Online (Sandbox Code Playgroud) 看起来这个问题应该很容易,但Grails(http://www.grails.org/Installation)的安装要求在2年内没有更新.有谁知道Grails 2.3将在JDK 8上运行吗?
当我执行此代码时,它会在流管道中打开大量文件:
public static void main(String[] args) throws IOException {
Files.find(Paths.get("JAVA_DOCS_DIR/docs/api/"),
100, (path, attr) -> path.toString().endsWith(".html"))
.map(file -> runtimizeException(() -> Files.lines(file, StandardCharsets.ISO_8859_1)))
.map(Stream::count)
.forEachOrdered(System.out::println);
}
Run Code Online (Sandbox Code Playgroud)
我得到一个例外:
java.nio.file.FileSystemException: /long/file/name: Too many open files
Run Code Online (Sandbox Code Playgroud)
问题是Stream.count当流完成后不会关闭流.但鉴于它是终端操作,我不明白为什么不应该这样做.对于诸如reduce和之类的其他终端操作也是如此forEach.flatMap另一方面关闭它所包含的流.
该文档告诉我使用try-with-resouces语句在必要时关闭流.在我的情况下,我可以count用这样的东西替换线:
.map(s -> { long c = s.count(); s.close(); return c; } )
Run Code Online (Sandbox Code Playgroud)
但这很嘈杂,并且在某些情况下可能会给大型复杂的管道带来真正的不便.
所以我的问题如下:
runtimizeException是一种在RuntimeExceptions 中包装已检查异常的方法.
我在Mac OS X 10.9.2和sbt 0.13.3-SNAPSHOT(从源代码构建),Java 8和sbt-proguard 0.2.2插件.
sbt 0.13.3-SNAPSHOT
[jacek]> sbtVersion
[info] 0.13.3-SNAPSHOT
Run Code Online (Sandbox Code Playgroud)
Java 8
$ /Library/Java/JavaVirtualMachines/jdk1.8.0.jdk/Contents/Home/bin/java -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)
Run Code Online (Sandbox Code Playgroud)
项目/ plugins.sbt
addSbtPlugin("com.typesafe.sbt" % "sbt-proguard" % "0.2.2")
Run Code Online (Sandbox Code Playgroud)
当我proguard:proguard在sbt shell中运行时,它引发了以下异常:
[sbt-updates]> show proguard:proguard
[info] ProGuard, version 4.9
[info] Reading program directory [/Users/jacek/oss/sbt-updates/target/scala-2.10/sbt-0.13/classes] (filtered)
[info] Reading program jar [/Users/jacek/.ivy2/cache/org.scalaz/scalaz-concurrent_2.10/bundles/scalaz-concurrent_2.10-7.1.0-M6.jar] (filtered)
[info] Reading program jar [/Users/jacek/.sbt/boot/scala-2.10.3/lib/scala-library.jar] (filtered) …Run Code Online (Sandbox Code Playgroud) 我有以下代码
public int solution(int X, int[] A) {
List<Integer> list = Arrays.asList(A);
Run Code Online (Sandbox Code Playgroud)
由于某种原因,它抛出了以下编译错误
Solution.java:11:错误:不兼容的类型:推理变量T具有不兼容的边界List list = Arrays.asList(A); ^等式约束:整数下限:int []其中T是一个类型变量:T扩展方法asList(T ...)中声明的Object
我假设这是一个Java 8功能,但我不知道如何解决该错误
我有一个Reflections库的问题.我试图动态加载实现特定接口的所有类.只要我不在这些类中使用lambda表达式(java 8),一切正常(所有类都已加载).我尝试升级lib版本,但效果是相同的(java.io.IOException:无效的常量类型:18).
依赖并在pom.xml中构建
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.10</version>
<exclusions>
<exclusion>
<groupId>javassist</groupId>
<artifactId>javassist</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.javassist</groupId>
<artifactId>javassist</artifactId>
<version>3.19.0-GA</version>
</dependency>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
Run Code Online (Sandbox Code Playgroud)
不排斥是同样的效果.
码:
URL jarUrl = jarFile.toURI().toURL();
URLClassLoader child = new URLClassLoader(new URL[]{jarUrl}, this.getClass().getClassLoader());
ConfigurationBuilder builder = new ConfigurationBuilder()
.addClassLoader(child)
.addUrls(jarUrl)
.setScanners(new SubTypesScanner());
Reflections r = new Reflections(builder);
return r.getSubTypesOf(cls);
Run Code Online (Sandbox Code Playgroud)
如何使用lambda表达式加载类?
PS抱歉英语:)
假设我们尝试向java 8流应用一个可能抛出已检查异常的lambda:
Stream<String> stream = Stream.of("1", "2", "3");
Writer writer = new FileWriter("example.txt");
stream.forEach(s -> writer.append(s)); // Unhandled exception: java.io.IOException
Run Code Online (Sandbox Code Playgroud)
这不会编译.
一种解决方法是嵌套已检查的异常,RuntimeException但它使以后的异常处理变得复杂,而且它只是丑陋:
stream.forEach(s -> {
try {
writer.append(s);
} catch (IOException e) {
throw new RuntimeException(e);
}
});
Run Code Online (Sandbox Code Playgroud)
另一种解决方法可能是转换有限的功能forEach,以普通的旧的foreach 循环是比较友好的检查的异常.
但天真的方法失败了:
for (String s : stream) { // for-each not applicable to expression type 'java.util.stream.Stream<java.lang.String>'
writer.append(s);
}
for (String s : stream.iterator()) { // foreach not applicable to type 'java.util.Iterator<java.lang.String>'
writer.append(s);
} …Run Code Online (Sandbox Code Playgroud) 我想采取以下方法:
public BigDecimal mean(List<BigDecimal> bigDecimals, RoundingMode roundingMode) {
BigDecimal sum = BigDecimal.ZERO;
int count=0;
for(BigDecimal bigDecimal : bigDecimals) {
if(null != bigDecimal) {
sum = sum.add(bigDecimal);
count++;
}
}
return sum.divide(new BigDecimal(count), roundingMode);
}
Run Code Online (Sandbox Code Playgroud)
并使用Streams api更新它.这是我到目前为止所得到的:
public BigDecimal average(List<BigDecimal> bigDecimals, RoundingMode roundingMode) {
BigDecimal sum = bigDecimals.stream()
.map(Objects::requireNonNull)
.reduce(BigDecimal.ZERO, BigDecimal::add);
long count = bigDecimals.stream().filter(Objects::nonNull).count();
return sum.divide(new BigDecimal(count), roundingMode);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在没有两次流式传输的情况下做到这一点(第二次获得计数)?
如何先分组,然后使用Java流应用过滤?
示例:考虑此类Employee:我希望按部门分组,其中包含薪水大于2000的员工列表.
public class Employee {
private String department;
private Integer salary;
private String name;
//getter and setter
public Employee(String department, Integer salary, String name) {
this.department = department;
this.salary = salary;
this.name = name;
}
}
Run Code Online (Sandbox Code Playgroud)
这就是我如何做到这一点
List<Employee> list = new ArrayList<>();
list.add(new Employee("A", 5000, "A1"));
list.add(new Employee("B", 1000, "B1"));
list.add(new Employee("C", 6000, "C1"));
list.add(new Employee("C", 7000, "C2"));
Map<String, List<Employee>> collect = list.stream()
.filter(e -> e.getSalary() > 2000)
.collect(Collectors.groupingBy(Employee::getDepartment));
Run Code Online (Sandbox Code Playgroud)
产量
{A=[Employee [department=A, salary=5000, name=A1]],
C=[Employee [department=C, …Run Code Online (Sandbox Code Playgroud) java-8 ×10
java ×8
java-stream ×4
bigdecimal ×1
collections ×1
collectors ×1
datetime ×1
for-loop ×1
foreach ×1
grails ×1
java-9 ×1
java-time ×1
javassist ×1
lambda ×1
proguard ×1
reflections ×1
sbt ×1