如何基于第一个元素合并多个数组列表?

时间:2015-11-13 09:05:40

标签: java arrays

我有几个字符串数组列表。我想基于每个数组的第一个元素将这个列表合并为一个。

基本上,我想合并这两个列表

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

在这一个

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

更多事情:

  • 列表顺序无关紧要
  • 数组顺序重要,因此如果值不存在,我必须添加填充

有人知道有效的方法吗?

我目前的做法

我当前的方法使用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]

1 个答案:

答案 0 :(得分: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