Java集合:如何将排序列表划分为子列表

时间:2010-11-01 22:19:49

标签: java collections

假设我有一个列表(EG:LinkedList<SomeObject>,其中包含按特定属性排序的元素(EG:SomeObject.someValue())。此属性可以且通常经常重复/它不是唯一的,但是永远不会为空。

有没有一种方便的方法可以将它分成多个列表,每个列表只包含其相等的基数顺序?此外,这只能在列表的一次迭代中完成吗?例如,原始列表:

1, 1, 1, 2, 2, 3, 3, 3

这个所需的清单:

1, 1, 1
2, 2,
3, 3, 3

6 个答案:

答案 0 :(得分:10)

不太方便,但是:

  • 开始循环。存储上一个项目,并将其与当前项目进行比较。
  • 如果之前的内容与当前不同(使用equals(..),请注意null),然后创建新的List,或使用list.subList(groupStart, currentIdx)

答案 1 :(得分:4)

您可以使用Apache CollectionUtils执行此操作,其中“list”是原始列表,“value”是您要为其提取子列表的对象的当前值:

Collection<SomeObject> selectedObjects = CollectionUtils
    .select(list,
            new Predicate() {
                boolean evaluate(Object input) {
                    return ((SomeObject) input).someValue().equals(value);    
                }
            });

这种方法意味着使用一个众所周知且经过良好测试的库(这总是一件好事),但缺点是你将为你需要的每个子列表遍历列表一次。

答案 2 :(得分:3)

非常确定没有针对此的Java API方法。但是你可以写:

 // This assumes your list is sorted according to someValue()
 // SomeValueType is the type of SomeObject.someValue()
 public Map<SomeValueType, List<SomeObject>> partition(List<SomeObject> list) {
    Object currValue = null;
    HashMap<SomeValueType, LinkedList<SomeObject>> result = new HashMap<SomeValueType, LinkedList<SomeObject>>();
    LinkedList<SomeObject> currList = null;

    for (SomeObject obj : list) {
        if (!obj.someValue().equals(currValue()) {
            currValue = obj.someValue();
            currList = new LinkedList<SomeObject>();
            result.put(currValue, currList);
        }
        currList.add(obj);
    }
}

这将返回HashMap个子列表,其中键为someValue,值为与其关联的分区列表。注意,我没有对此进行测试,因此不要只复制代码。

编辑:使这个返回散列图而不是arraylist。

答案 3 :(得分:3)

如果您使用Google Guava-libaries

import com.google.common.collect.HashMultiset;
import com.google.common.collect.Lists;

public class Example {
    public static void main(String[] args) {
        HashMultiset<Integer> ints = HashMultiset.create();
        ints.addAll(Lists.newArrayList(1, 1, 1, 2, 2, 3, 3, 3));
        System.out.println(ints);
    }
}

输出:

[1 x 3, 2 x 2, 3 x 3]

如果您需要计算使用ints.count(x);的x的元素数量,如果您有值类型,则不需要更多,只需计算。

答案 4 :(得分:3)

答案 5 :(得分:1)

这应该有用(未经测试,但我很确定一切正常,这也假设列表的内容是可排序的):

public static List[] getEquivalentSubLists( List parent )
{

    List cloneList = parent.clone();
    Collections.sort(cloneList);

    ArrayList<List> returnLists;
    int end;
    while (cloneList.size() > 0)
    {
        end = cloneList.lastIndexOf(cloneList.get(0));

        returnLists.add(cloneList.subList(0, end));
        cloneList.removeAll(cloneList.subList(0, end));
    }

    return returnList.toArray();
}