我有一份人员名单。 人bean具有以下结构:
class Person {
private String name;
private String occupation;
/* Getters and setters*/
/* toString method */
}
此列表位于ArrayList<Person>
。
问题是当我打印数据时,我得到:
Foo, scientist
Foo, teacher
Bar, student
我想像这样打印:
Foo, scientist, teacher
Bar, student
那么,我该如何自动分组数据呢?
感谢。
答案 0 :(得分:2)
如果您正在寻找一个干净的图书馆,可以使用emaze-dysfunctional编写
Groups.groupBy(persons, new Pluck<String, Person>(Person.class, "occupation"))
获得Map<String, List<Person>>
。
答案 1 :(得分:1)
这可以通过多种方式解决。我可能会使用Map对象,比如说
Map<String, List<String>> occupationsByName = new LinkedHashMap<String, List<String>>(0);
然后我会循环遍历人员列表,使用名称作为Map对象的键并初始化List对象,只要我发现该键以前不存在于Map中,
for ( Iterator<String> persons = personsList.iterator(); persons.hasNext() ) {
String person = persons.next().getName();
if ( occupationsByName.containsKey( person ) ) {
occupationsByName.get( person ).add( person.getOccupation() );
} else {
occupationsByName.put(person, new ArrayList<String>(0) );
occupationsByName.get( person ).add( person.getOccupation() );
}
}
然后我会将职业添加到每个键下的List中,然后最后打印出Map。
我必须声明我假设您知道如何使用集合类,即使您没有,也可以使用Java API
答案 2 :(得分:0)
如果你有两个Person
实例具有相同的名称但职业不同,并且你认为它们是同一个人那么你需要告诉JVM如果两个名字相等,那么那些人也是等于。你可以通过覆盖equals()
现在第二步是更新列表,以便一旦您尝试添加列表中已存在的Person
(即,有一个人具有相同的名称),那么您将新的职业添加到旧的(例如通过字符串连接)。
您不需要任何库来执行您想要的操作,只需要编写完整的类。 :)
答案 3 :(得分:0)
此测试用例传递给我:
package com.sandbox;
import com.google.common.base.Joiner;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Multimap;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
public class SandboxTest {
@Test
public void testQuestionInput() {
List<Person> persons = new ArrayList<Person>();
persons.add(new Person("Foo", "scientist"));
persons.add(new Person("Foo", "teacher"));
persons.add(new Person("Bar", "student"));
String outputString = getOutputString(persons);
assertEquals("Foo, scientist, teacher\n" +
"Bar, student\n", outputString);
}
private String getOutputString(List<Person> in) {
Multimap<String, String> map = LinkedListMultimap.create();
for (Person person : in) {
map.put(person.name, person.occupation);
}
StringBuilder buf = new StringBuilder();
Joiner joiner = Joiner.on(", ");
for (String key : map.keySet()) {
buf.append(key).append(", ").append(joiner.join(map.get(key))).append("\n");
}
return buf.toString();
}
class Person {
Person(String name, String occupation) {
this.name = name;
this.occupation = occupation;
}
private String name;
private String occupation;
/* Getters and setters*/
/* toString method */
}
}
它接受人员列表并将其传递到Multimap。 The Multimap comes from the Google guava library.
但是,你可能想要使用maurocchi的答案。它比这更干净。
答案 4 :(得分:0)
如果要按名称对数据进行分组。然后使用“比较器”。
例如:
Comparator comparator = new TestComparator();
Collections.sort(listTobeSorted, comparator);
现在,我们将在listTobeSorted中有一个排序列表。所以你可以按照自己的意愿打印数据。
//新的内部类
public class TestComparator implements Comparator<Person > {
@Override
public int compare(Person o1, Person o2) {
//To write logic, Please refer the tutorial for Comparator
}
}
我希望这会对您的问题有所帮助。
答案 5 :(得分:0)
根据您的问题,我假设您的名单中的人员名称相同,实际上是同一个人。如果是这样,您应该重新考虑您的数据组织。 例如,您可以为每个人存储职业列表。
class Person {
private String name;
private final List<String> occupations = new ArrayList<String>();
public boolean addOccupation(String occupation) {
return occupations.add(occupation);
}
// getters
}
通过名称对人员进行分组最好使用Map而不是List。 然后,您可以编写一个简单的打印方法,如下所示:
String personsToString(Map<String, Person> personMap) {
StringBuilder sb = new StringBuilder();
for (Person person: personMap.values())
sb.append(person.getName()).append(", ").append(person.getOccupations()).append("\n");
return sb.toString();
}