Java:将List拆分为两个子List?

37

在Java中,最简单、最标准、或者最高效的方法是将一个List分成两个子List。原始的List可以进行修改,无需进行复制。方法签名可能如下:

public void split(List<T> original, List<T> firstHalf, List<T> secondHalf);

/** Split a list into two sublists. The original list will be modified to
 * have size i and will contain exactly the same elements at indices 0 
 * through i-1 as it had originally; the returned list will have size 
 * len-i (where len is the size of the original list before the call) 
 * and will have the same elements at indices 0 through len-(i+1) as 
 * the original list had at indices i through len-1.
 */
<T> List<T> split(List<T> list, int i);
[编辑] List.subList 返回原始列表的视图,如果修改了原始列表,则该视图将无效。因此,split 不能使用 subList,除非它也放弃了对原始引用的使用(或者,如Marc Novakowski的答案所示,使用 subList,但立即复制结果)。

“最高效”不是取决于List的具体类型吗? - Miserable Variable
你的注释应该以"/**"开头,因为它是一个方法注释。 - Steve Kuo
Hemal,可能是这样。所以请给我最简单和最标准的方法。 - Chris Conway
1
@Hemal:幸运的是,使用subList()可以让每个列表实现最快的操作。 - Joachim Sauer
14个回答

0
同样地,借鉴Marc的清单,我们将使用List.removeAll()从第二个列表中删除重复的条目。请注意,严格来说,如果原始列表包含重复项,则这仅遵循规格:否则,原始列表可能会缺少项目。
<T> List<T> split(List<T> list, int i) {
        List<T> x = new ArrayList<T>(list.subList(i, list.size()));
        // Remove items from end of original list
        list.removeAll(x);
        return x;
}

我认为这个解决方案在两个分区中都出现了.equals()元素的情况下会失败。 - Brandon DuRette

0

我的解决方案:

List<X> listToSplit = new ArrayList<X>();

List<X> list1 = new ArrayList<X>();
List<X> list2 = new ArrayList<X>();

for (X entry : listToSplit)
{
    if (list1.size () > list2.size ())
        list2.add (entry);
    else
        list1.add( entry );
}

应该可以工作 :)


0
//Here is my list
    ArrayList<T> items=new ArrayList<T>();
    Integer startIndex = 0;
            int j = 0;
            for (; j < items.size() - 1; j++) {//always start with next index not again 0
                for (int i = 0; i < 4; i++) { // divide into equal part with 4 item
                    startIndex = startIndex + 1;
                    j = startIndex;
                }
            }

0
使用流(streams)的解决方案,对每个项目使用切换/翻转布尔值进行分区:
Collection<String> big = ...;
AtomicBoolean switcheroo = new AtomicBoolean();
Map<Boolean, List<String>> subLists = big.stream()
        .collect(Collectors.partitioningBy(o -> switcheroo.getAndSet(!switcheroo.get())));

你最终得到一个包含两个条目的映射,键是 truefalse,值是子列表。
这并不完全回答原始问题,但你可以使用 AtomicInteger 每次递增而不是使用 AtomicBoolean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接