如何在java中操作列表

时间:2009-06-21 16:12:11

标签: java collections

修改:我的列表按来自数据库的顺序排序 我有一个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()
       }
    }

5 个答案:

答案 0 :(得分:5)

对我来说,这似乎是使用Multimap的好例子,它允许为单个密钥存储多个值。

Google Collections实施Multimap

这可能意味着Person对象的ssnterminationReason字段可能必须分别作为键和值取出。 (这些字段将被假定为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)

两个可能的问题:

  • 如果您的列表未排序
  • ,则无效
  • 您没有对 ob.getTerminationReason()做任何事情。我认为你的意思是将它添加到上一个对象。

答案 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();

}