如何转置List <list>?</list>

时间:2010-05-31 07:27:22

标签: java collections arraylist

我有一个以下的ArrayList,

[Title,Data1,Data2,Data3]
[A,2,3,4]
[B,3,5,7]

我想像这样转换这个,

[Title,A,B]
[Data1,2,3]
[Data2,3,5]
[Data3,4,7]

我对这种方法感到有点困惑。任何提示都会非常感激。

感谢。

12 个答案:

答案 0 :(得分:12)

这称为换位。以下代码段可满足您的需求:

import java.util.*;
public class ListTranspose {
    public static void main(String[] args) {
        Object[][] data = {
            { "Title", "Data1", "Data2", "Data3" },
            { "A", 2, 3, 4 },
            { "B", 3, 5, 7 },
        };
        List<List<Object>> table = new ArrayList<List<Object>>();
        for (Object[] row : data) {
            table.add(Arrays.asList(row));
        }
        System.out.println(table); //  [[Title, Data1, Data2, Data3],
                                   //   [A, 2, 3, 4],
                                   //   [B, 3, 5, 7]]"
        table = transpose(table);
        System.out.println(table); //  [[Title, A, B],
                                   //   [Data1, 2, 3],
                                   //   [Data2, 3, 5],
                                   //   [Data3, 4, 7]]
    }
    static <T> List<List<T>> transpose(List<List<T>> table) {
        List<List<T>> ret = new ArrayList<List<T>>();
        final int N = table.get(0).size();
        for (int i = 0; i < N; i++) {
            List<T> col = new ArrayList<T>();
            for (List<T> row : table) {
                col.add(row.get(i));
            }
            ret.add(col);
        }
        return ret;
    }
}

另见

答案 1 :(得分:4)

这是我的解决方案。感谢@ jpaugh的代码。我希望这会对你有所帮助。^ _ ^

public static <T> List<List<T>> transpose(List<List<T>> list) {
   final int N = list.stream().mapToInt(l -> l.size()).max().orElse(-1);
   List<Iterator<T>> iterList = list.stream().map(it->it.iterator()).collect(Collectors.toList());
   return IntStream.range(0, N)
       .mapToObj(n -> iterList.stream()
       .filter(it -> it.hasNext())
       .map(m -> m.next())
       .collect(Collectors.toList()))
   .collect(Collectors.toList());
}

答案 2 :(得分:2)

这称为转置操作。代码示例是here,但是需要进行重大修改,因为你有一个数组ArrayList(我从你的问题推断)

答案 3 :(得分:2)

这样的事可能

List<List<String>> list = new ArrayList<List<String>>(firstList.size());
for(int i = 0; i < firstList.size(); i++) {
   list.add(Arrays.asList(
      firstList.get(i),
      secondList.get(i),
      thirdList.get(i))
   );
}

答案 4 :(得分:2)

背后的数学:你需要transpose矩阵。如果你使用二维数组或“列表列表”,这更容易,这与集合几乎相同。数组列表也可以工作,但稍微有些混乱。

This wikipedia article显示了一些换位算法。

答案 5 :(得分:2)

该技术称为转置。实施示例。

public static MyObject [][] transpose(MyObject [][] m){
    int r = m.length;
    int c = m[r].length;
    MyObject [][] t = new MyObject[c][r];
    for(int i = 0; i < r; ++i){
        for(int j = 0; j < c; ++j){
            t[j][i] = m[i][j];
        }
    }
    return t;
}

答案 6 :(得分:1)

您需要使用二维数组。 看here

答案 7 :(得分:1)

检查所有列表是否具有相同的大小。

将信息放在Matrix(例如List with List元素)中,以获取列表的数量和列表的大小。

使用旋转的尺寸信息创建一个新的Matrix。 (3x4到4x3)

实现2 For循环并将元素放入新矩阵。

答案 8 :(得分:1)

您是否拥有固定数量的ArrayLists并且它们是否具有固定大小?如果它是固定的,你可以做的是有一个int索引值并在同一个循环中依次处理每个ArrayList。然后,您可以将每个值传输到临时ArrayList,然后在最终的ArrayList中对此进行引用以进行输出。

听起来很混乱?这是一个粗略的解决方案:

ArrayList tempList = new ArrayList();
ArrayList outputList = new ArrayList();

for(index=0;index<list1.getsize();index++){
// Add null checks and other validation here
tempList.add( list1.get(index) );
tempList.add( list2.get(index) );
tempList.add( list3.get(index) );
outputList.add( tempList );
}

答案 9 :(得分:1)

如果是用于数据迁移任务,如果尺寸不是太大,您可以考虑使用友好的电子表格。

对于矩阵操作的东西,jScience库有矩阵支持。如果只是转换一个矩阵,那就太过分了,但这取决于需要做些什么。

答案 10 :(得分:0)

由于get(index)可能会严重损害您的性能,即对于大型链表,我建议使用@polygenelubricants解决方案但使用迭代器方法。

public static <T> List<List<T>> transpose(List<List<T>> table) {
        List<List<T>> ret = new ArrayList<List<T>>();
        final int N = table.stream().mapToInt(l -> l.size()).max().orElse(-1);
        Iterator[] iters = new Iterator[table.size()];

        int i=0;
        for (List<T> col : table) {
            iters[i++] = col.iterator();
        }

        for (i = 0; i < N; i++) {
            List<T> col = new ArrayList<T>(iters.length);
            for (Iterator it : iters) {
                col.add(it.hasNext() ? (T) it.next() : null);
            }
            ret.add(col);
        }
        return ret;
    }

答案 11 :(得分:0)

不是一种快速的方法,也不是最干净的方法,而是更多的 kotlin-ish 代码。

fun <T> List<List<T>>.transpose(): List<List<T>> {
    val result = (first().indices).map { mutableListOf<T>() }.toMutableList()
    forEach { list -> result.zip(list).forEach { it.first.add(it.second) } }
    return result
}

第一行创建一个 M 大小的“结果”列表(对于 NxM 原始矩阵),而第二行 =>

  1. 首先遍历所有列表 'a'(每个列表大小为 m)
  2. 将 a 的第 i 个项目附加到结果中的第 i 个列表。