假设我有一个整数列表,我在列表中使用Java 8 forEach方法将其值加倍.说我有以下代码:
List<Integer> l = Arrays.asList(2,3,6,1,9);
l.forEach(p->p*=2);
Run Code Online (Sandbox Code Playgroud)
至于每个方法采取消费者并称之为接受方法.我运行上面的代码后打印列表,原始列表不会更改.
据我所知,Stream不会改变源代码,但在这里我只是在每个元素上调用accept方法......
谢谢你的推荐
这是我的代码
List<Integer> ints = Stream.of(1,2,4,3,5).collect(Collectors.toList());
Integer maxInt = ints.stream()
.max(Comparator.comparing(i -> i))
.get();
System.out.println("Maximum number in the set is " + maxInt);
Run Code Online (Sandbox Code Playgroud)
输出:
Maximum number in the set is 5
Run Code Online (Sandbox Code Playgroud)
我不能i在我的代码的下面两部分之间进行distingues
Comparator.comparing(i -> i)
Run Code Online (Sandbox Code Playgroud)
任何人都可以善待并解释两者之间的区别i吗?
我有以下代码,它有点抽象我在Java程序中的实际实现:
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = bufferedReader.readLine()) != null) {
String lineReference = line;
runLater(() -> consumeString(lineReference));
}
Run Code Online (Sandbox Code Playgroud)
这里我需要使用lambda表达式的引用副本,当我尝试使用时line我得到:
从lambda表达式引用的局部变量必须是最终的或有效的final
对我来说这似乎很尴尬,因为我所做的就是获取对象的新引用,这是编译器也可以自己解决的问题.
所以,我要说line是有效决赛在这里,因为它只是变得回路中的分配和其他地方.
任何人都可以对此有所了解并解释为什么这里需要它以及为什么编译无法解决它?
我花了一些时间来学习Java 8的一些新功能.作为练习,我使用一些Java 8功能接口编写了一个MergeSort.我在下面包含完整的代码(可能存在错误/优化,如果它们与Java 8功能相关,我只对它们感兴趣).我的问题是,我相信在使用我的功能界面时有机会利用lambda表达式,但它还没有点击我的大脑.感觉就像每次我打电话申请,我应该有一种方法可以使用" - >"代替.有人可以给我看灯吗?
public class Merge implements BinaryOperator<int[]>{
@Override
public int[] apply(int[] t, int[] u) {
int[] result = new int[t.length + u.length];
for (int i = 0, j = 0, k = 0; i < result.length; i++){
if( j == t.length){
result[i] = u[k++];
} else if (k == u.length) {
result[i] = t[j++];
} else {
result[i] = t[j] < u [k] ? t[j++] : u[k++];
}
}
return result;
}
}
Run Code Online (Sandbox Code Playgroud)
public …Run Code Online (Sandbox Code Playgroud) 我现在正在学习新的Java 8功能,经过4年专门在C#世界,所以lambdas对我来说是最重要的.我现在正在努力寻找C#的"OfType"方法的等价物.
我所拥有的是List myNodes,我想从中获取一个List,其中Node是一个接口,而SpecificNode正在实现它.
在C#中它会是
IList<INode> myNodes = new List<INodes>(){new SpecificNode(), new OtherNode()}
IList<SpecificNode> specificNodes = myNodes.OfType<SpecificNode>()
Run Code Online (Sandbox Code Playgroud) 我可以使用以下语法序列化lambda:
Runnable r = (Runnable & Serializable) () -> System.out.println("");
try (ObjectOutput oo = new ObjectOutputStream(new ByteArrayOutputStream())) {
oo.writeObject(r);
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我从客户端代码收到lambda并且它没有被正确转换,我就无法序列化它.
如何r在不更改其定义的情况下序列化以下内容:
Runnable r = () -> System.out.println("");
Run Code Online (Sandbox Code Playgroud)
我试图序列化"派生"对象:
Runnable r1 = (Runnable & Serializable) r::run;
Runnable r2 = (Runnable & Serializable) () -> r.run();
Run Code Online (Sandbox Code Playgroud)
但在每种情况下,都oo.writeObject(rxxx);失败了NotSerializableException.
我在例子中从字符串中获取毫秒数时遇到麻烦.到目前为止,我已经尝试了这三种不同的方式,示例显示了最新的尝试.似乎总是认为TemporalAccessor不支持ChronoField.如果我可以成功构建一个Instant实例,我可以使用toEpochMilli().
String dateStr = "2014-08-16T05:03:45-05:00"
TemporalAccessor creationAccessor = DateTimeFormatter.ISO_OFFSET_DATE_TIME.parse(dateStr);
Instant creationDate = Instant.from(creationAccessor);
Run Code Online (Sandbox Code Playgroud)
请提供简明的答案(不要从头开始构建格式化程序)并仅使用java 8标准发行版(我可以使用Joda,但希望避免依赖项).
编辑:上面代码中的Instant.from抛出:java.time.DateTimeException: Unable to obtain Instant from TemporalAccessor: {OffsetSeconds=-18000},ISO resolved to 2014-08-16T05:03:45 of type java.time.format.Parsed
我看看Java 8新闻与7相比,除了lambdas或新时间框架之类的非常有趣的东西,我发现引入了一个新功能(?):默认方法.
我在本文中找到了以下示例:
public interface Math {
int add(int a, int b);
default int multiply(int a, int b) {
return a * b;
}
}
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很奇怪.上面的代码看起来像一个abstract带有实现方法的类.那么,为什么要在接口中引入默认方法呢?这种方法的实际优势是什么?
在同一篇文章中,我读到了这个解释:
为什么要在接口中添加方法?我们之所以这是因为接口与它们的实现类太紧密耦合了.即,在不破坏实现者类的情况下,无法在接口中添加方法.在接口中添加方法后,其实现的所有类必须声明此新方法的方法体.
嗯,这根本不能说服我.恕我直言我相信,当一个类实现一个接口时,必须为其中的每个方法声明方法体.这肯定是一个约束,但它也证实了它的"本质"(如果你明白我的意思......)
如果你对每个继承类都有共同的逻辑,那么你将把它放到一个实现abstract类中.
那么,默认方法的真正优势是什么?(看起来更像是一种解决方法,而不是新功能...)
更新 我理解这种方法是为了向后兼容,但它仍然不能让我这么说服.接口表示类必须具有的行为.所以实现某个接口的类肯定会有这种行为.但是,如果有人可以随意更改界面,则此约束会被破坏.行为可以随时改变......我错了吗?
我创建了两个ZonedDateTime对象,我认为它们应该是相同的:
public static void main(String[] args) {
ZoneId zid = ZoneId.of("America/New_York");
ZoneOffset offset = ZoneOffset.from(LocalDateTime.now().atZone(zid));
ZonedDateTime zdt0 = ZonedDateTime.of(2014, 8, 24, 21, 10, 1, 777000002, offset);
ZonedDateTime zdt1 = ZonedDateTime.of(2014, 8, 24, 21, 10, 1, 777000002, zid);
boolean equals = Objects.equals(zdt0, zdt1);
System.out.println("equals: " + equals);
}
Run Code Online (Sandbox Code Playgroud)
在调试器中,我看到ZonedDateTime 区域的成员类在第一种情况下是java.time.ZoneOffset,在第二种情况下是java.time.ZoneRegion,这使得ZonedDateTime对象不相等.这令人困惑......有什么想法吗?
我有一个Set<String> usernames
和List<Player> players
我想过滤掉那些不属于Set的玩家.
我知道如何在Vanilla pre Java 8中做到这一点
List<Player> distinctPlayers = new ArrayList<Player>();
for(Player p : players) {
if(!usernames.contains(p.getUsername()) distinctPlayers.add(p);
}
Run Code Online (Sandbox Code Playgroud)
我试图用Lambda表达式编写这个简单的代码,但我很难usernames.contains()在过滤器中工作
players.stream().filter(!usernames.contains(p -> p.getUsername()))
.collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)
这不编译."无法恢复方法getUsername()"