我有一个Person用这些属性定义的类:
private String name;
private String surname;
private Date birthday;
Run Code Online (Sandbox Code Playgroud)
我希望得到一个生日的最大值Collection<Person>.
在Java 7中,没有外部库,我会这样做:
public Date maxAgeJava7(Collection<Person> persons) {
Date max = null;
for (Person person : persons) {
if (max == null || person.getBirthday().after(max)) {
max = person.getBirthday();
}
}
return max;
}
Run Code Online (Sandbox Code Playgroud)
现在,在Java 8中,可以像这样编写它:
public Date maxAgeJava8(Collection<Person> persons) {
return persons.stream().map(Person::getBirthday).max((Date d1, Date d2)-> d1.compareTo(d2)).get();
}
Run Code Online (Sandbox Code Playgroud)
这要好得多但我不喜欢这部分:
(Date d1, Date d2)-> d1.compareTo(d2)
Run Code Online (Sandbox Code Playgroud)
作为Date implements Comparable,有没有办法告诉Java使用该compareTo()方法,而不必明确地编写它?
考虑下面的代码,
class DemoStatic {
public static Runnable testStatic() {
return () -> {
System.out.println("Run");
};
}
public void runTest () {
Runnable r = DemoStatic::testStatic;
r.run();
}
}
public class MethodReferenceDemo {
public static void main(String[] args) {
DemoStatic demo = new DemoStatic();
demo.runTest();
}
}
Run Code Online (Sandbox Code Playgroud)
run()应该调用Runnable正由testStatic方法返回的实例的方法.控制台上的输出应为"运行".
但是这段代码没有调用run()实例的方法,r也没有任何东西在控制台中打印出来.
有人可以解释原因.
如果我没有正确使用方法参考"::",请评论.
假设我有两个double数组.我一直在尝试使用Java 8中的Stream.我想我已经理解了主要的想法,但后来我意识到我不确定如何同时操作两个Streams.
例如,我想计算两个数组的协方差.
public class foo {
public static double mean(double[] xs) {
return Arrays.stream(xs).average().getAsDouble();
}
public static void main(String[] args) {
double[] xs = {1, 2, 3, 4, 5, 6, 7, 8, 9};
double[] ys = {1517.93, 1757.78, 1981.1, 2215.73, 2942.66, 3558.32, 4063.91, 4521.16, 5101.76, 5234.12};
System.out.println("Mean of xs: " + mean(xs));
double xs_sumDeviation = Arrays.stream(xs)
.boxed()
.mapToDouble(d -> d.doubleValue() - mean(xs))
.sum();
// Covariance
double covXY = Arrays.stream(xs, ys)
.mapToDouble(x,y -> {
double numerator = (x-mean(xs)* (y-mean(ys);
double …Run Code Online (Sandbox Code Playgroud) 假设我有以下手工制作的功能界面:
@FunctionalInterface
public static interface OnHandCardAddedListener extends HandView {
@Override
void onCardAdded(final Card card);
@Override
default void onCardPlayed(final int cardIndex) { }
@Override
default void onCardsSwapped(final int cardIndexOne, final int cardIndexTwo) { }
}
Run Code Online (Sandbox Code Playgroud)
它是签名Card -> void,因此该功能接口的实现是lambda,它是Consumer<Card>功能接口的实现.
我知道我可能应该在界面中使用默认方法扩展Consumer<Card>和实现它.applyOnHandCardAddedListener
但为什么不只是开箱即用?
使用以下测试:
private void acceptConsumer(final Consumer<Card> cardConsumer) {
}
Run Code Online (Sandbox Code Playgroud)
和测试代码:
Consumer<Card> cardConsumer = card -> { };
acceptConsumer(cardConsumer);
OnHandCardAddedListener viewCardConsumer = card -> { };
acceptConsumer(viewCardConsumer); // does not compile
Run Code Online (Sandbox Code Playgroud)
这里acceptConsumer(viewCardConsumer)不编译,但为什么不编译?据我所知,他们应该解决相同类型的lambda,因此两者都可以用于具体的定义.
编辑 …
作为我上一篇文章的后续内容是通过Collections.synchronizedSet(...)进行迭代.forEach()保证是线程安全的吗?我将分享我对我认为实施中的错误的看法,以验证它确实是一个错误.
我们有一个SynchronizedCollection<E>这里,可以通过调用Collections.synchronizedCollection(...)JDK来源获得:
public static <T> Collection<T> synchronizedCollection(Collection<T> c) {
return new SynchronizedCollection<>(c);
}
Run Code Online (Sandbox Code Playgroud)
static class SynchronizedCollection<E> implements Collection<E>, Serializable {
private static final long serialVersionUID = 3053995032091335093L;
final Collection<E> c; // Backing Collection
final Object mutex; // Object on which to synchronize
SynchronizedCollection(Collection<E> c) {
this.c = Objects.requireNonNull(c);
mutex = this;
}
SynchronizedCollection(Collection<E> c, Object mutex) {
this.c = Objects.requireNonNull(c);
this.mutex = Objects.requireNonNull(mutex);
}
public int size() {
synchronized (mutex) {return c.size();}
}
public …Run Code Online (Sandbox Code Playgroud) 为什么.next()返回7而不是8,就像我预期的那样?
List<Integer> intList = new ArrayList<>();
IntStream.range(0, 10)
.forEach(i -> intList.add(i));
int value = intList.stream()
.filter(number -> number == 7)
.iterator()
.next(); // returns 7, not 8.
Run Code Online (Sandbox Code Playgroud) 我最近升级到java,我正在尝试接口的新默认方法.但是我不断在令牌"default"上获得语法错误,删除此令牌.这是我的构建路径,我预计会出现问题:
![在这里输入图像描述]![[1]](https://i.stack.imgur.com/FjEiJ.png)
我怀疑它与我的构建路径有关,但不知道是什么.如果它与我的代码有关,这里是我正在尝试的代码:
interface Test{
default void sayHelloWorld() {
System.out.println("Hello World");
}
}
Run Code Online (Sandbox Code Playgroud)
有人有任何想法吗?
考虑我想使用Java 8流API打印文件列表的行.我该怎么写呢?
这不是我的真实情况,只是一种非常简化的形式.
File[] files;
Arrays.stream(files). // what now?
Run Code Online (Sandbox Code Playgroud)
我想过把它映射File到Stream<String>但是后来我卡住了.
我有一个Play 2.2我正在使用Java 8 的应用程序,我无法上班.代码使用OpenJDK 1.8为我本地编译,但是当我尝试将代码推送到Heroku时,我得到以下错误,这是我在本地早些时候出现的错误,当我在意外运行OpenJDK 1.7 with lambdas时.
java.lang.RuntimeException: Unknown constant: 18
Run Code Online (Sandbox Code Playgroud)
我设置system.properties使用Java 1.8,我知道这是有效的,因为它启动时使用以下文本:
Play 2.x - Java app detected
-----> Installing OpenJDK 1.8...done
Run Code Online (Sandbox Code Playgroud)
有没有我忘记更新到Java 8的东西?
我尝试更新PATH以及此处指定但没有做任何事情.
假设我有接口A,它只有一个声明如下的方法:
interface A{
void print();
}
Run Code Online (Sandbox Code Playgroud)
现在使用旧的java风格,我们将以匿名的方式使用它,如下所示:
new A() {
@Override
public void print() {
System.out.println("in a print method");
}
};
Run Code Online (Sandbox Code Playgroud)
并使用lambda表达式,我们将使用它如下:
() -> "A1";
Run Code Online (Sandbox Code Playgroud)
现在我的问题是,如果接口A有两个声明如下的方法:
interface A{
void print();
void display();
}
Run Code Online (Sandbox Code Playgroud)
它以前的匿名函数利用方式如下:
new A() {
@Override
public void print() {
System.out.println("in print");
}
@Override
public void display() {
System.out.println("in display");
}
};
Run Code Online (Sandbox Code Playgroud)
现在如何将显示方法转换为lambda?或者我们不被允许这样做; 如果不是为什么不呢?为什么我们不能代表它
print() - >"打印"
和
display() - >"显示"
java ×10
java-8 ×10
lambda ×4
java-stream ×3
collections ×1
eclipse ×1
heroku ×1
interface ×1
iterator ×1
statistics ×1