[英]Leverage Java stream API to retrieve data from objects holding streamable collections themselves
In my architecture there are data objects which I intend to display in a structured fashion.在我的架构中,有一些我打算以结构化方式显示的数据对象。 These objects look like this:
这些对象看起来像这样:
public class A
{
private final String a1;
public A( String a1 )
{
this.a1 = a1;
}
public String getA1()
{
return a1;
}
}
public class B
{
private final String b1;
private final List<A> bList;
public B( String b1, List<A> list )
{
this.b1 = b1;
this.bList = list;
}
public String getB1()
{
return b1;
}
public List<A> getBList()
{
return bList;
}
}
public class C
{
private final String c1;
private final int c2;
private final List<B> cList;
public C( String c1, int c2, List<B> list )
{
this.c1 = c1;
this.c2 = c2;
this.cList = list;
}
public String getC1()
{
return c1;
}
public int getC2()
{
return c2;
}
public List<B> getCList()
{
return cList;
}
}
So an object C
holds some values, as well as a list of objects B
and those objects B
hold some values of their own as well as respectively a list of objects A
, which in turn hold some values themselves.因此 object
C
包含一些值,以及对象B
的列表,这些对象B
包含它们自己的一些值以及对象 A 的列表,而对象A
本身又包含一些值。
The requirements I am trying to comply with are putting these into a JSON structure and also create a list of objects, where every entry looks like a collection of all of those data properties in a single object .我试图遵守的要求是将这些放入 JSON 结构中,并创建一个对象列表,其中每个条目看起来都像是单个 object 中所有这些数据属性的集合。 The latter is supposed to look like this:
后者应该是这样的:
public class D
{
public final String a1;
public final String b1;
public final String c1;
public final int c2;
public D( String a1, String b1, String c1, int c2 )
{
this.a1 = a1;
this.b1 = b1;
this.c1 = c1;
this.c2 = c2;
}
}
The declared goal is to have those collected in a List<D>
.声明的目标是将那些收集在
List<D>
中。
The JSON structuring was easy to accomplish with Jackson: JSON 结构很容易用 Jackson 完成:
C c = someGetterForC();
ObjectMapper mapper = new ObjectMapper();
mapper.enable( SerializationFeature.INDENT_OUTPUT );
try
{
return mapper.writeValueAsString( c );
}
catch( JsonProcessingException e )
{
// do error handling here
}
This gives me a well formatted JSON string and complies with the first requirement.这给了我一个格式良好的 JSON 字符串并符合第一个要求。 For the second requirement I initially used a very trivial approach, ie simply to collect all data in
for
-loops, thereby creating instances of D
and putting them in a list.对于第二个要求,我最初使用了一种非常简单的方法,即简单地在
for
循环中收集所有数据,从而创建D
的实例并将它们放入列表中。 This looked somewhat like this:这看起来有点像这样:
List<D> dList = new ArrayList<>();
C c = someGetterForC();
for( B b : c.getCList() )
{
for( A a : b.getBList() )
{
D d = new D( a.getA1(), b.getB1(), c.getC1(), c.getC2() )
dList.add( d );
}
}
However I would like to learn to do this using Java-Streams in order to create instances of D
, because I am still having trouble with understanding some of its concepts.但是我想学习使用 Java-Streams 来创建
D
的实例,因为我仍然无法理解它的一些概念。 The struggle I am facing is with我面临的斗争是
A
after streaming lists of object B
B
列表之后流式传输对象列表A
A
, B
and C
in the same call and collecting them in instances of D
A
、 B
和C
的非列表成员,并在D
的实例中收集它们Can this be done in a single stream-API call, ie这可以在单个流 API 调用中完成吗,即
C c = someGetterForC();
c.stream()
// how to continue?
and if so, does it make sense to do so?如果是这样,这样做有意义吗?
for
-loops there will be redundant data in the instances of D
is of no concern and intendedfor
循环,在D
的实例中会有冗余数据这一事实是无关紧要的,也是有意为之的Assume there is an object C c_alpha
which holds:假设有一个 object
C c_alpha
包含:
c1 = "car"
c2 = 42;
cList = {b_alpha, b_beta}
Where B b_alpha
holds:其中
B b_alpha
成立:
b1 = "boulder"
bList = {a_alpha}
And B b_beta
holds: B b_beta
成立:
b1 = "bomb"
bList = {a_beta, a_gamma}
Lastly there are the type A
objects left, A a_alpha
holds:最后剩下类型
A
对象, A a_alpha
持有:
a1 = "ape"
A a_beta
holds: A a_beta
持有:
a1 = "andromeda"
And A a_gamma
holds: A a_gamma
成立:
a1 = "axe"
Then the collected list of objects D
that I am trying to get by leveraging the stream-API should look like this:然后,我试图通过利用流 API 获取的对象
D
的收集列表应如下所示:
{ "42", "car", "boulder", "ape" },
{ "42", "car", "bomb", "andromeda" },
{ "42", "car", "bomb", "axe" },
Given objects which hold primitive types + strings as members, as well as lists of objects, which in turn hold primitive types + strings as members as well as lists of objects - how to stream them in a single call to retrieve tuples of the primitive types + strings accross all types in a single call?给定将原始类型 + 字符串作为成员的对象,以及对象列表,这些对象又将原始类型 + 字符串作为成员以及对象列表 - 如何在一次调用中 stream 它们以检索原始类型的元组+ 在一次调用中跨所有类型的字符串?
I realize this is hard to properly formulate, the example above should clear things up.我意识到这很难正确表述,上面的例子应该清楚了。
In order to get the same result as with your classical for-loop approach you need to use flatMap
.为了获得与经典 for 循环方法相同的结果,您需要使用
flatMap
。 Get the list of B
s from your object and stream over it, flatmap and get every A
for each B
by calling getBList()
and map the data to a new D
object and finally collect to list of D
objects.从您的 object 和 stream 中获取
B
的列表,通过调用getBList()
和 map 将数据平面化并获取每个B
的每个A
到新的D
object,最后收集到D
对象列表。 Something like below should give you what you are looking for像下面这样的东西应该会给你你正在寻找的东西
C c = someGetterForC();
List<D> dList = c.getCList()
.stream()
.flatMap(b -> b.getBList()
.stream()
.map(a -> new D(a.getA1(), b.getB1(), c.getC1(), c.getC2())))
.collect(Collectors.toList());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.