2015-11-13 38 views
1

我有几个字符串数组列表。我想根据每个数组的第一个元素将这些列表合并到一个列表中。如何合并几个基于第一个元素的数组列表?

基本上,我想在这一个

[key4,a,a,a,null,null] 
[key3,null,null,null,c,c] 
[key2,a,a,a,b,b] 
[key1,a,a,a,b,b] 

一些更多的东西合并这两个列表

ArrayList<String[]> list1 = new ArrayList<String[]>(); 
list1.add(new String[]{"key1","a","a","a"}); 
list1.add(new String[]{"key2","a","a","a"}); 
list1.add(new String[]{"key4","a","a","a"}); 

ArrayList<String[]> list2 = new ArrayList<String[]>(); 
list2.add(new String[]{"key1","b","b"}); 
list2.add(new String[]{"key2","b","b"}); 
list2.add(new String[]{"key3","c","c"}); 

  • 列表顺序并不重要
  • 阵列订单是重要,所以我必须添加填充如果值不存在

有人知道有效的方法来做到这一点吗?

我目前的做法

我目前的做法使用一个HashMap来存储密钥(数组的第一个元素)

HashMap<String, String[]> results = new HashMap<String, String[]>(); 
process(list1); 
process(list2); 

void process(ArrayList<String[]> list) { 
    for(String[]s : list) { 
     if(!results.containsKey(s[0])) { 
      results.put(s[0], Arrays.copyOfRange(s, 1, s.length)); 
     } else { 
      String[] current = results.get(s[0]); 
      results.put(s[0], concat(current, Arrays.copyOfRange(s, 1, s.length))); 
     } 
    } 
} 

这给我的输出中(不正确的,因为没有“填充”)

key4 [a, a, a] 
key3 [c, c] 
key2 [a, a, a, b, b] 
key1 [a, a, a, b, b] 
+0

是否所有的数组总是有表1和2中相同的长度? – user1438038

+0

在同一列表中,数组的长度相同。但是list1和list2中的数组可以有不同的大小。 – ThomasThiebaud

+0

并且列表2还可以包含一个不是*列表1中存在的键吗? – user1438038

回答

1

基本上,你需要做的是检查list2如果所需的密钥存在。如果是这样,只需合并数组。但是,如果密钥在list2中不存在,则必须添加填充数组。这可以通过返回一个具有所需长度的新数组来完成。

看一看下面我的代码:

public void mergeArrays() { 

    ArrayList<String[]> list1 = new ArrayList<String[]>(); 
    list1.add(new String[] { "key1", "a", "a", "a" }); 
    list1.add(new String[] { "key2", "a", "a", "a" }); 
    list1.add(new String[] { "key4", "a", "a", "a" }); 

    ArrayList<String[]> list2 = new ArrayList<String[]>(); 
    list2.add(new String[] { "key1", "b", "b" }); 
    list2.add(new String[] { "key2", "b", "b" }); 
    list2.add(new String[] { "key3", "c", "c" }); 

    ArrayList<String[]> result = new ArrayList<String[]>(); 

    // Merge list1 to list2 
    for (String[] array1: list1) { 
    // Find key from list1 in list2 
    int index = this.findIndex(array1[0], list2); 

    // Key was found, merge arrays 
    if (index > -1) { 
     result.add(this.concat(array1, list2.get(index))); 
    } 
    // Key was not found, use padding 
    else { 
     // Padding second array with null values 
     result.add(this.concat(array1, this.padding(list2.get(0).length, null))); 
    } 
    } 

    // Merge list2 to list1 
    for (String[] array2: list2) { 
    // Find key from list2 in list1 
    int index = this.findIndex(array2[0], list1); 

    // Key was not found, use padding 
    if (index == -1) { 
     // Padding first array with null values 
     String[] temp = this.concat(this.padding(list1.get(0).length, null), array2); 
     temp[0] = array2[0]; // Set key 
     result.add(temp); 
    } 
    } 

    // Debug output 
    for (String[] array: result) { 
    for (int i = 0; i < array.length; ++i) { 
     System.out.print(array[i] + " "); 
    } 
    System.out.println(""); 
    } 
} 

// Return array with padding 
private String[] padding(final int size, final String padding) { 
    String[] result = new String[size]; 
    Arrays.fill(result, padding); 

    return result; 
} 

// Find needle in haystack and return index 
private int findIndex(final String needle, final ArrayList<String[]> haystack) { 
    for (int i = 0; i < haystack.size(); ++i) { 
    if (haystack.get(i)[0].equals(needle)) { 
     return i; 
    } 
    } 

    return -1; 
} 

// Merge two arrays, omit first element of second array 
private String[] concat(String[] arrayOne, String[] arrayTwo) { 
    int arrayOneLength = arrayOne.length; 
    int arrayTwoLength = arrayTwo.length; 

    String[] result = new String[arrayOneLength + arrayTwoLength - 1]; 
    System.arraycopy(arrayOne, 0, result, 0, arrayOneLength); 
    System.arraycopy(arrayTwo, 1, result, arrayOneLength, arrayTwoLength - 1); // Skip key in second array 

    return result; 
} 

输出:

key1 a a a b b 
key2 a a a b b 
key4 a a a null null 
key3 null null null c c 
+0

它是否适用于2个以上的列表? – ThomasThiebaud

+0

你可以改变''mergeArrays()'',例如返回结果并提供两个参数传入''list1''和''list2''。然后,您将可以使用不同的参数多次调用该方法,并合并两个以上的列表。 – user1438038

+1

我做到了,它工作正常。我只需要像'mergeArrays(list1,mergeArrays(list2,list3))'这样将链接调用到'mergeArrays'。感谢您的回答 – ThomasThiebaud

相关问题