我有一个以下的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]
我对这种方法感到有点困惑。任何提示都会非常感激。
感谢。
答案 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 原始矩阵),而第二行 =>