使用 Java 流 API 对第一个元素执行操作,然后对列表中的所有项目执行操作

问题描述 投票:0回答:1

我想迭代对象列表两次。第一次我只需要使用第一个对象并执行一些操作。第二次我想对列表中的所有项目进行操作。

在下面的示例中,我有一个名为

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"
        }
    ]
}
java list java-stream
1个回答
0
投票

这里有两种方法。但首先,我创建了类。 我没有使用构建器,而是使用了

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]

这是一个流解决方案。

  • 流式传输 testPojoList
  • 使用
    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())))
© www.soinside.com 2019 - 2024. All rights reserved.