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

发布于 2024-09-30 01:15:38 字数 347 浏览 2 评论 0原文

假设我有一个列表(EG:LinkedList),其中包含按某个属性排序的元素(EG:SomeObject.someValue())。此属性通常可以并且通常确实经常重复/它不是唯一的,但有没有

一种方便的方法可以将其划分为多个列表,每个列表仅包含其基本顺序相同的列表?另外,可以仅通过列表的一次迭代来完成此操作吗? ? 例如,原始列表:

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

所需的列表来自:

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

Let's say I have a list (EG: LinkedList<SomeObject>that contains elements ordered by a certain attribute (EG: SomeObject.someValue()). This attribute can and usually does repeat often/it isn't unique, BUT is never null.

Is there a convenient way to divide this into multiple Lists, each list containing only its equal in cardinal order? Also, can this be done with only once iteration of the list? For example, the original list:

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

The desired lists from this:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

明媚如初 2024-10-07 01:15:38

不太方便,但是:

  • 开始一个循环。存储前一项,并将其与当前项进行比较。
  • 如果前一个与当前不同(使用equals(..),并小心null),则创建一个新的List,或使用list.subList(groupStart, currentIdx)

Not too convenient, but:

  • start a loop. Store the previous item, and compare it to the current.
  • if the previous is different from the current (using equals(..), and be careful with null), then create a new List, or use list.subList(groupStart, currentIdx)
放赐 2024-10-07 01:15:38

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

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

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

You could use Apache CollectionUtils to do this, where "list" is the original list, and "value" is the current value of the objects you want to extract a sublist for:

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

This approach means using a well known and well tested library (which always is a good thing), but the downside is that you will loop through the list once for each sublist you need.

东京女 2024-10-07 01:15:38

很确定没有 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,值是与其关联的分区列表。注意,我没有对此进行测试,所以不要只是复制代码。

编辑:使此返回哈希图而不是数组列表。

Pretty sure there isn't a java API method for this. However you can write:

 // 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);
    }
}

This will return you an HashMap of sublists, where the key is the someValue and the value is the partitioned list associated to it. Note, I didn't test this, so don't just copy the code.

EDIT: made this return hashmap instead of arraylist.

我不吻晚风 2024-10-07 01:15:38

如果您使用 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]

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

If you would use 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);
    }
}

Output:

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

If you need to count how many elements of x you have use ints.count(x);, if you have value types you do not need to have more then just count.

穿透光 2024-10-07 01:15:38

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

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();
}

This should work (untested, but I am pretty sure everything is ok, This also assumes that the contents of the list are sortable):

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文