什么是一个方法的Java 8功能接口什么都不带,什么都不返回?
即,相当于Action
带void
返回类型的C#参数?
为了利用java.util.stream
Jdk 8中包含的各种查询方法,我尝试设计域模型,其中具有*
多重性(具有零个或多个实例)的关系的getter 返回a Stream<T>
而不是Iterable<T>
or Iterator<T>
.
我怀疑的是,与此Stream<T>
相比,Iterator<T>
是否会产生任何额外的开销?
那么,使用Stream<T>
?来破坏我的域模型是否有任何不利之处?
或者,我应该总是返回一个Iterator<T>
或者Iterable<T>
,并通过将该迭代器转换为StreamUtils
?来让最终用户决定是否使用流.
请注意,返回a Collection
不是有效选项,因为在这种情况下,大多数关系都是惰性且大小未知.
最新版本的VS Code已经提供了一种简单的运行单个测试的方法,如Tyler Long对.NET Core和Visual Studio Code中的调试xunit测试问题的回答所指出的那样.
但是,我正在寻找如何运行VS Code中的测试套件类中包含的所有测试(无需调试)?
我找到的唯一方法是添加到launch.json
特定配置,如下所示,但我只能在调试中运行(我想在没有调试的情况下运行它):
{
"name": ".NET Core Xunit tests",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "/usr/local/share/dotnet/dotnet",
"args": ["test"],
"cwd": "${workspaceRoot}/test/MyProject.Tests",
"externalConsole": false,
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart"
}
Run Code Online (Sandbox Code Playgroud) 例如在.Net中,它提供了具有不同数量和类型的参数的Action
委托的几个实现(相当于Java Consumer
功能接口),我期望Java 8提供了一些方法来指定Consumer
不同类型的多个参数.
我知道在Java中我们不能定义具有相同名称的不同类型,这些类型在泛型类型参数中有所不同,但是提供多参数会有很好的流畅替代方案Consumer
.
有没有简单的方法可以做到这一点,这不需要定义新的功能界面?
有一个重载方法,collect()
在Stream<T>
与以下签名的接口中:
<R> R collect(Supplier<R> supplier,
BiConsumer<R,? super T> accumulator,
BiConsumer<R,R> combiner)
Run Code Online (Sandbox Code Playgroud)
还有另一个版本collect(Collector<? super T,A,R> collector)
,它接收具有前三个功能的对象.Collector
对应的接口的属性combiner
具有签名BinaryOperator<A> combiner()
.
在后一种情况下,Java API 8声明:
组合器函数可以将状态从一个参数折叠到另一个参数并返回该参数,或者可以返回新的结果容器.
为什么前collect
一种方法也没有收到BinaryOperator<R>
呢?
允许对结果流进行多次迭代,CompletableFuture<Stream<String>>
我正在考虑以下方法之一:
将生成的未来转换为CompletableFuture<List<String>>
:teams.thenApply(st -> st.collect(toList()))
将生成的未来转换为Flux<String>
缓存:Flux.fromStream(teams::join).cache();
Flux<T>
是Publisher<T>
项目反应堆的实施.
使用案例:
我想Stream<String>
从一个数据源获得一个具有顶级联赛球队名称的序列(例如),该数据源提供一个League
对象Standing[]
(基于足球数据RESTful API,例如http://api.football-data.org/v1/ soccerseasons/445/leagueTable).使用AsyncHttpClient
和Gson
我们有:
CompletableFuture<Stream<String>> teams = asyncHttpClient
.prepareGet("http://api.football-data.org/v1/soccerseasons/445/leagueTable")
.execute()
.toCompletableFuture()
.thenApply(Response::getResponseBody)
.thenApply(body -> gson.fromJson(body, League.class));
.thenApply(l -> stream(l.standings).map(s -> s.teamName));
Run Code Online (Sandbox Code Playgroud)
要重新使用生成的流,我有两个选择:
1. CompletableFuture<List<String>> res = teams.thenApply(st -> st.collect(toList()))
2. Flux<String> res = Flux.fromStream(teams::join).cache()
Run Code Online (Sandbox Code Playgroud)
Flux<T>
不那么冗长,并提供我所需要的一切.然而,在这种情况下使用它是否正确?
或者我应该使用CompletableFuture<List<String>>
?或者还有其他更好的选择吗?
更新了一些想法(2018-03-16):
CompletableFuture<List<String>>
:
List<String>
将继续收集,当我们需要继续处理未来的结果时,可能已经完成了.List<T>
.Flux<String> …
我正在将库项目迁移到.net标准,当我尝试使用System.Reflection
API调用时,我收到以下编译错误Type:GetProperties()
:
类型不包含'GetProperties'的定义
这是我的project.json
:
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable"
},
"dependencies": {},
"frameworks": {
"netstandard1.6": {
"dependencies": {
"NETStandard.Library": "1.6.0"
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
给定现有ICollection<T>
实例(例如dest
)从IEnumerable<T>
?添加项目的最有效和可读方式是什么?
在我的用例中,我有一些实用方法Collect(IEnumerable items)
,它返回一个ICollection
带有元素的new items
,所以我按照以下方式进行:
public static ICollection<T> Collect<T>(IEnumerable<T> items) where T:ICollection<T>
{
...
ICollection<T> dest = Activator.CreateInstance<T>();
items.Aggregate(dest, (acc, item) => { acc.Add(item); return acc; });
...
return dest;
}
Run Code Online (Sandbox Code Playgroud)
问题:这样做是否有"更好"的方式(更有效或可读)?
更新:我认为使用它Aggregate()
是非常流畅的,并不像调用那么低效ToList().ForEach()
.但它看起来不太可读.由于没有其他人同意使用Aggregate()
我想阅读你的理由不用Aggregate()
于此目的.
在这种情况下,只有奇数行具有有意义的数据,并且没有唯一标识这些行的字符.我的目的是获得与以下示例等效的内容:
Stream<DomainObject> res = Files.lines(src)
.filter(line -> isOddLine())
.map(line -> toDomainObject(line))
Run Code Online (Sandbox Code Playgroud)
没有共享全球状态,有没有"干净"的方式去做?
Java API文档声明combiner
该collect
方法的参数必须是:
用于组合两个值的关联,非干扰,无状态函数,它必须与累加器函数兼容
A combiner
是BiConsumer<R,R>
接收两个类型的参数R
并返回void
.但是文档没有说明我们是否应该将元素组合到第一个或第二个参数中?
例如,以下示例可以给出不同的结果,取决于组合的顺序是: m1.addAll(m2)
或m2.addAll(m1)
.
List<String> res = LongStream
.rangeClosed(1, 1_000_000)
.parallel()
.mapToObj(n -> "" + n)
.collect(ArrayList::new, ArrayList::add,(m1, m2) -> m1.addAll(m2));
Run Code Online (Sandbox Code Playgroud)
我知道在这种情况下我们可以简单地使用方法句柄,例如ArrayList::addAll
.然而,在某些情况下需要Lambda并且我们必须以正确的顺序组合项目,否则我们可能在并行处理时得到不一致的结果.
这是否在Java 8 API文档的任何部分中声明了?或者它真的没关系?
java-8 ×7
java ×6
java-stream ×6
.net-core ×2
c# ×2
.net ×1
domain-model ×1
generics ×1
ienumerable ×1
lambda ×1
linq ×1
rx-java ×1
xunit.net ×1