我最近在代码中尽可能地使用了流,但是我遇到了一个我无法解决的问题。
我有一个名为' Listing'的简单类:
package models;
public class House {
private boolean isPrivate;
private Integer views;
private boolean hasSessionId;
public Listing(boolean isPrivate, Integer views, boolean hasSessionId) {
this.isPrivate = isPrivate;
this.views = views;
this.hasSessionId = hasSessionId;
}
public boolean hasSessionId() {
return hasSessionId;
}
public boolean isPublic() {
return !isPrivate;
}
public boolean isPrivate() {
return isPrivate;
}
public Integer getViews() {
return views;
}
}
我有一个房子列表,我想要制作一个包含两个列表的地图,其中的房屋通过某些条件隔离,我希望一个列表包含私人住宅,无论他们是否有会话ID,另一个列表包含公共有会话ID的房子。
使用传统循环我可以实现我想要的功能,但我希望能够将其转换为使用流。
下面的测试类包含两个测试,第一个测试shouldProduceTwoListsWithOneElementEach
使用传统的每个循环并遍历房屋列表并生成两个列表,一个包含privateHouses,另一个包含公共房屋或带有sessionId的房屋
第二个测试shouldSeperateWhetherHouseIsPrivate
是我最初使用流的尝试,目前测试在第二个断言失败,因为partitioningBy逻辑只是拆分房屋对象是否是私有的,因此是一个公共房屋做没有会话最终被添加到另一个列表,通过segregatedHouses.get(false)访问。
package models;
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
public class ListingsTest {
private List<House> houses;
@Before
public void setUp() {
House publicListingWithSession = new House(false, 1, true);
House privateListingWithoutSession = new House(true, 1, false);
House publicListingWithNoViewsWithoutSession = new House(false, 0, false);
this.houses = new ArrayList<House>();
this.houses.add(publicListingWithSession);
this.houses.add(privateListingWithoutSession);
this.houses.add(publicListingWithNoViewsWithoutSession);
}
@Test
public void shouldProduceTwoListsWithOneElementEach() {
List<House> privateHouses = new ArrayList<House>();
List<House> publicHousesOrHasSessionId = new ArrayList<House>();
for (House listing : houses) {
if (listing.isPrivate()) {
privateHouses.add(listing);
} else if (listing.getViews() > 0 || listing.hasSessionId()) {
publicHousesOrHasSessionId.add(listing);
}
}
assertEquals(1, privateHouses.size());
assertEquals(1, publicHousesOrHasSessionId.size());
}
@Test
public void shouldSeperateWhetherHouseIsPrivate() {
Map<Boolean, List<House>> segregatedHouses = houses.stream()//
.collect(Collectors.partitioningBy(p -> p.isPrivate()));
assertEquals(1, segregatedHouses.get(true).size());
assertEquals(1, segregatedHouses.get(false).size());
}
}
因此,如果谓词p -> p.isPrivate()
的计算结果为true,则House
对象将添加到Map<Boolean, List<House>> segregatedHouses
,可以通过segregatedHouses.get(true)
访问。如果谓词的计算结果为false,那么House
会被添加到另一个列表中,是否有一种方法可以在将House添加到将通过segregatedHouses.get(false)
访问的列表之前再次对其进行评估?
任何帮助非常感谢!
答案 0 :(得分:3)
我相信在第二部分中,你只想要私有的房子或者是公共的房子,并且hasSessionId被分成2个列表。
试试这个......
Map<Boolean, List<House>> segregatedHouses = houses.stream()
.filter(p -> p.isPrivate() || p.hasSessionId())
.collect(Collectors.partitioningBy(p -> p.isPrivate()))