我想迭代对象列表两次。第一次我只需要使用第一个对象并执行一些操作。第二次我想对列表中的所有项目进行操作。
在下面的示例中,我有一个名为
TestPojo
的 testPojoList
列表。
使用 Java 流 API,我尝试通过 2 个步骤实现相同的目标(操作 #1 和操作 #2)是否有更好的方法或者我可以将这两个操作合并到单个操作中?代码如下:
public void Mapping() {
TestPojo testPojo1 = TestPojo.builder().name("Mike").city("Denver").company("Tesla").build();
TestPojo testPojo2 = TestPojo.builder().name("Bob").city("Atlanta").company("Tesla").build();
TestPojo testPojo3 = TestPojo.builder().name("Steve").city("Chicago").company("Tesla").build();
TestPojo testPojo4 = TestPojo.builder().name("John").city("Boston").company("Tesla").build();
List<TestPojo> testPojoList = Arrays.asList(testPojo1, testPojo2, testPojo3, testPojo4);
//Operation1
TransformedTestPojo transformedTestPojo = testPojoList.stream().findFirst().map(testPojo -> mapCompanyName(testPojo)).orElse(null);
//Operation2
List<PersonalDetails> personalDetailsList = testPojoList.stream().map(testPojo -> mapOtherDetails(testPojo)).collect(Collectors.toList());,
transformedTestPojo.setPersonalDetailsList(personalDetailsList);
System.out.println(transformedTestPojo);
}
private PersonalDetails mapOtherDetails(TestPojo testPojo) {
return PersonalDetails.builder().name(testPojo.getName()).City(testPojo.getCity()).build();
}
private TransformedTestPojo mapCompanyName(TestPojo testPojo) {
return TransformedTestPojo.builder().company(testPojo.getCompany()).build();
}
public class TestPojo {
String name;
String city;
String company;
}
public class TransformedTestPojo {
String company;
List<PersonalDetails> personalDetailsList;
}
public class PersonalDetails {
String name;
String City;
}
以下是输入和所需的输出:
需求清单:
{
"testPojoList": [
{
"name": "Mike",
"city": "Denver",
"company": "Tesla"
},
{
"name": "Bob",
"city": "Atlanta",
"company": "Tesla"
},
{
"name": "Steve",
"city": "Chicago",
"company": "Tesla"
},
{
"name": "John",
"city": "Boston",
"company": "Tesla"
}
]
}
响应对象:
"TransformedTestPojo":
{
"company": "Tesla",
"personalDetailsList": [
{
"name": "Mike",
"City": "Denver"
},
{
"name": "Bob",
"City": "Atlanta"
},
{
"name": "Steve",
"City": "Chicago"
},
{
"name": "John",
"City": "Boston"
}
]
}
这里有两种方法。但首先,我创建了类。 我没有使用构建器,而是使用了
TestPojo
的构造函数。但它仍然有效。
class TestPojo {
String name;
String city;
String company;
public TestPojo(String name, String city, String company) {
this.name = name;
this.city = city;
this.company = company;
}
public String getName() {
return name;
}
public String getCity() {
return city;
}
public String getCompany() {
return company;
}
@Override
public String toString() {
return String.format("[%s, %s, %s]", name, city, company);
}
}
class TransformedTestPojo {
String company;
List<PersonalDetails> personalDetailsList;
public TransformedTestPojo(String company,
List<PersonalDetails> personalDetailsList) {
this.company = company;
this.personalDetailsList = personalDetailsList;
}
public String getCompany() {
return company;
}
public List<PersonalDetails> getPersonalDetailsList() {
return personalDetailsList;
}
}
class PersonalDetails {
String name;
String City;
public PersonalDetails(String name, String city) {
this.name = name;
City = city;
}
@Override
public String toString() {
return String.format("[%s, %s]", name, City);
}
}
数据
List<TestPojo> testPojoList =
List.of(new TestPojo("Mike", "Denver", "Tesla"),
new TestPojo("Bob", "Atlanta", "Tesla"),
new TestPojo("Steve", "Chicago", "Tesla"),
new TestPojo("John", "Boston", "Tesla"));
使用循环的 Map 方法
最好的方法(imo)是使用
Map
接口的 Java 8 功能
testPojoList
Map.compute
将获取一个键,然后如果值为 null,则创建一个。 否则,它将使用现有值。TransformedTestPojo
和新的 key (company)
创建一个新的 ArrayList<>()
实例以存储个人详细信息。Map<String, TransformedTestPojo> map = new HashMap<>();
for (TestPojo tp : testPojoList) {
map.compute(tp.getCompany(),
(k, v) -> v == null ? new TransformedTestPojo(k,
new ArrayList<>()) : v)
.getPersonalDetailsList().add(new PersonalDetails(
tp.getName(), tp.getCity()));
}
创建地图后,获取地图值(具有
TransformedTestPojo
实例)并作为集合返回。
Collection<TransformedTestPojo> collection = map.values();
请注意,创建的是 Collection (List 的超类型),而不是 List。如果需要列表,您可以执行以下操作。
List<TransformedTestPojo> list = new ArrayList<>(map.values());
显示结果
list.forEach(k -> {
System.out.println(k.getCompany());
k.getPersonalDetailsList()
.forEach(p -> System.out.println(" " + p));
});
打印
Tesla
[Mike, Denver]
[Bob, Atlanta]
[Steve, Chicago]
[John, Boston]
这是一个流解决方案。
Collectors.groupingBy
以公司为钥匙PersonalDetails
个实例。entrySet
的 map
并构建 TransformedTestPojo
List<TransformedTestPojo> list1 = testPojoList.stream()
.collect(Collectors.groupingBy(TestPojo::getCompany,
Collectors.mapping(
tp -> new PersonalDetails(
tp.getName(), tp.getCity()),
Collectors.toList())))
.entrySet().stream()
.map(e -> new TransformedTestPojo(e.getKey(),
e.getValue()))
.toList();
}
请注意,可以使用地图本身来代替返回的
List<TransformedTestPojo>
。 key
是 company name
,该值包含 PersonalDetails
的列表。 如果这有用,那么您所需要的就是以下内容:
Map<String, List<PersonalDetails>> result = testPojoList.stream()
.collect(Collectors.groupingBy(TestPojo::getCompany,
Collectors.mapping(
tp -> new PersonalDetails(
tp.getName(), tp.getCity()),
Collectors.toList())))