修改:我的列表按来自数据库的顺序排序 我有一个ArrayList,其中包含类People的对象。人们有两个属性:ssn和terminationReason。所以我的列表看起来像这样
ArrayList:
ssn TerminatinoReason
123456789 Reason1
123456789 Reason2
123456789 Reason3
568956899 Reason2
000000001 Reason3
000000001 Reason2
我想更改此列表,以便没有重复项,并且逗号分隔终止原因。
所以上面的列表将成为
New ArrayList:
ssn TerminatinoReason
123456789 Reason1, Reason2, Reason3
568956899 Reason2
000000001 Reason3, Reason2
我正在进行一些事情,我正在循环查看原始列表并匹配ssn,但它似乎不起作用。
有人可以帮忙吗?
我使用的代码是:
String ssn = "";
Iterator it = results.iterator();
ArrayList newList = new ArrayList();
People ob;
while (it.hasNext())
{
ob = (People) it.next();
if (ssn.equalsIgnoreCase(""))
{
newList.add(ob);
ssn = ob.getSSN();
}
else if (ssn.equalsIgnoreCase(ob.getSSN()))
{
//should I get last object from new list and append this termination reason?
ob.getTerminationReason()
}
}
答案 0 :(得分:5)
对我来说,这似乎是使用Multimap
的好例子,它允许为单个密钥存储多个值。
这可能意味着Person
对象的ssn
和terminationReason
字段可能必须分别作为键和值取出。 (这些字段将被假定为String
。)
基本上,它可以如下使用:
Multimap<String, String> m = HashMultimap.create();
// In reality, the following would probably be iterating over the
// Person objects returned from the database, and calling the
// getSSN and getTerminationReasons methods.
m.put("0000001", "Reason1");
m.put("0000001", "Reason2");
m.put("0000001", "Reason3");
m.put("0000002", "Reason1");
m.put("0000002", "Reason2");
m.put("0000002", "Reason3");
for (String ssn : m.keySet())
{
// For each SSN, the termination reasons can be retrieved.
Collection<String> termReasonsList = m.get(ssn);
// Do something with the list of reasons.
}
如有必要,可以生成逗号分隔的Collection
列表:
StringBuilder sb = new StringBuilder();
for (String reason : termReasonsList)
{
sb.append(reason);
sb.append(", ");
}
sb.delete(sb.length() - 2, sb.length());
String commaSepList = sb.toString();
这可以再次设置为terminationReason
字段。
Jonik在评论中提到的另一种方法是使用StringUtils.join
中的Apache Commons Lang方法创建逗号分隔列表。
还应该注意,Multimap
没有指定实现是否应该允许重复的键/值对,因此应该查看要使用的Multimap
类型。 / p>
在此示例中,HashMultimap
是一个不错的选择,因为它不允许重复的键/值对。这将自动消除为某个特定人员提供的任何重复原因。
答案 1 :(得分:3)
List<People> newlst = new ArrayList<People>();
People last = null;
for (People p : listFromDB) {
if (last == null || !last.ssn.equals(p.ssn)) {
last = new People();
last.ssn = p.ssn;
last.terminationReason = "";
newlst.add(last);
}
if (last.terminationReason.length() > 0) {
last.terminationReason += ", ";
}
last.terminationReason += p.terminationReason;
}
您将获得newlst中的聚合列表。
更新:如果您使用的是MySQL,则可以使用GROUP_CONCAT功能以所需格式提取数据。我不知道其他数据库引擎是否具有类似的功能。
更新2:删除了不必要的排序。
答案 2 :(得分:3)
您可能需要的是哈希。 HashMap可能有用。
在People Class中覆盖equals()和hashCode()。
让hashCode返回人(人)SSN。这样,您将在同一个“存储桶”中拥有具有相同SSN的所有People对象。
请记住,Map接口实现类使用键/值对来保存对象,因此您将拥有类似myHashMap.add(“ssn”,peopleobject)的内容;
答案 3 :(得分:1)
两个可能的问题:
答案 4 :(得分:0)
编辑:现在我看到您已编辑了您的问题。
当您的列表被排序时,(通过我假设的ssn)
Integer currentSSN = null;
List<People> peoplelist = getSortedList();//gets sorted list from DB.
/*Uses foreach construct instead of iterators*/
for (People person:peopleList){
if (currentSSN != null && people.getSSN().equals(currentSSN)){
//same person
system.out.print(person.getReason()+" ");//writes termination reason
}
else{//person has changed. New row.
currentSSN = person.getSSN();
system.out.println(" ");//new row.
system.out.print(person.getSSN()+ " ");//writes row header.
}
}
如果您不想显示列表中的内容,可以使用它来创建MAP,然后使用它,如下所示。
如果您的列表未排序
也许你应该尝试一种不同的方法,使用Map。在这里,ssn将是地图的关键,值可以是人物列表
Map<Integer,List<People>> mymap = getMap();//loads a Map from input data.
for(Integer ssn:mymap.keyset()){
dorow(ssn,mymap.get(ssn));
}
public void dorow(Integer ssn, List<People> reasons){
system.out.print(ssn+" ");
for (People people:reasons){
system.out.print(people.getTerminationReason()+" ");
}
system.out.println("-----");//row separator.
最后但并非最不重要的一点是,你应该覆盖People类的hashCode()和equals()方法。
例如
public void int hashcode(){
return 3*this.reason.hascode();
}