如何从String对象中获取Java模型对象?

时间:2016-08-26 03:01:25

标签: java list java-8

我有一个模型类:

public class Person{
    private String personnelId;
    private String lastName;
    private String firstName;
}

现在我有服务类

public class A{
    @Autowired
    private OfficerService officer;

    public List<Person> getAccounts(Param param){
        List<Person> personList = personDao.getAccounts(param);
        List<String> stringList = personList.stream().map(Person::getPersonnelId).collect(Collectors.toList());
        List<String> list = Officer.getVisiblePerson(stringList);
        List<Person> visiblePersonList= new ArrayList<>();

        return visiblePersonList;
    }

现在,我将List<Person>转换为List<String>,从Model类中获取personnelId。方法调用后,我回来personnelId。我需要转换回List<Person>,其中包含{Id}附加firstNamelastNamePerson的所有数据。我怎么能这样做?

编辑:

Map<String, Person> personMap = personList.stream()
        .collect(Collectors.toMap(Person::getPersonnelId, person -> person));
    List<Person> visiblePersonList = list.stream()
        .map(id -> personMap.get(id))
        .collect(Collectors.toList());

收到地图时收到错误:

The method collect(Collector<? super String,A,R>) in the type Stream<String> is not applicable for the arguments (Collector<Person,capture#2-of ?,Map<String,Object>>)

我做错了什么?

2 个答案:

答案 0 :(得分:2)

一种方法是将它放在地图中,然后从地图中获取这些值。还有一个额外的迭代,但是根据列表的大小或它是否可以并行,性能会稍微或多或少。

public static void main(String[] args) throws Exception {
    List<Person> personList = new ArrayList<Person>(); // personDao.getAccounts(param);

    Person person1 = new Person("1", "ln1", "fn1");
    Person person2 = new Person("2", "ln2", "fn2");
    Person person3 = new Person("3", "ln3", "fn3");
    Person person4 = new Person("4", "ln4", "fn4");
    personList.add(person1);
    personList.add(person2);
    personList.add(person3);
    personList.add(person4);

/*Of interest , the logic*/
        List<String> stringList = personList.stream().map(Person::getPersonnelId).collect(Collectors.toList());
        Map<String, Person> mapStringToPerson = personList.stream()
                .collect(Collectors.toMap(Person::getPersonnelId, person -> person));

/*as a logic filter even number id , in a real life this will be officer filter*/
            List<String> listFiltered = stringList.stream().filter(personId -> (Integer.parseInt(personId) % 2 == 0))
                    .collect(Collectors.toList());// Officer.getVisiblePerson(stringList);
            List<Person> visiblePersonList = listFiltered.stream().filter(id -> mapStringToPerson.containsKey(id))
                    .map(id -> mapStringToPerson.get(id)).collect(Collectors.toList());
            visiblePersonList.forEach(System.out::println);

}

打印::

    Person with id : 2 and name fn2 ln2
    Person with id : 4 and name fn4 ln4

答案 1 :(得分:1)

首先,让我解决一些命名问题:

  • Officer应为officer

  • stringList应该命名为idList,因为它是概念上包含的内容。您没有为该类型命名,因为:

    1. 您可以通过查看... (您猜对了) ...类型。
    2. 说“字符串”没有意义,也没有说明字符串代表什么。
  • 同样,list应命名为visibleIdList

现在我将使用我刚刚建议的名称。

由于getVisiblePerson()会返回idList中可见的条目列表,即已过滤的列表,因此您可以执行以下两项操作之一:

  1. 创建Map<String, Person> idPerson,然后迭代visibleIdList并查找Person并构建一个列表。

  2. visibleIdList变成visibleIdSet,然后重复personList并过滤到Set中的那些。

  3. 选项2的内存占用量更小,性能也更好。