【问题标题】:Join two arrays in Java? [duplicate]在Java中加入两个数组? [复制]
【发布时间】:2012-11-15 00:46:05
【问题描述】:

可能重复:
How to concatenate two arrays in Java?

我有两个对象

HealthMessage[] healthMessages1;
HealthMessage[] healthMessages2;

HealthMessage[] healthMessagesAll;

healthMessages1 = x.getHealth( );   
healthMessages2 = y.getHealth( );

我应该如何加入这两个对象,所以我只能返回一个:

return healthMessagesAll;

推荐的方式是什么?

【问题讨论】:

  • 试试this
  • 您想如何处理重复项?假设 Array1 有 3 个重复而不考虑 Array2,那么所有 3 个重复都应该在 resultantArray 中可用?
  • 好问题 Kaipa,没想到重复。
  • 最后在 Java 8 中可以使用一行,在stackoverflow.com/a/23188881/466677中描述

标签: java


【解决方案1】:

使用 Apache Commons Collections API 是一个好方法:

healthMessagesAll = ArrayUtils.addAll(healthMessages1,healthMessages2);

【讨论】:

  • +1 表示不重新发明轮子。如果你可以使用 Apache Commons,那就更优雅了。
【解决方案2】:

我会分配一个总长度为healthMessages1healthMessages2 的数组,并使用System.arraycopy 或两个for 循环来复制它们的内容。这是System.arraycopy 的示例:

public class HelloWorld {

     public static void main(String []args) {

        int[] a = new int[] { 1, 2, 3};
        int[] b = new int[] { 3, 4, 5};
        int[] r = new int[a.length + b.length];
        System.arraycopy(a, 0, r, 0, a.length);
        System.arraycopy(b, 0, r, a.length, b.length);

        // prints 1, 2, 3, 4, 5 on sep. lines
        for(int x : r) {
            System.out.println(x);
        }            
     }         
}

【讨论】:

    【解决方案3】:

    这样写起来更直观,不用处理数组索引:

    Collection<HealthMessage> collection = new ArrayList<HealthMessage>();
    collection.addAll(Arrays.asList(healthMessages1));
    collection.addAll(Arrays.asList(healthMessages2));
    
    HealthMessage[] healthMessagesAll = collection.toArray(new HealthMessage[] {});
    

    .. 但不要问我它与System.arraycopy 相比的性能。

    【讨论】:

    • +1 一个漂亮、干净、简单的解决方案
    【解决方案4】:

    我会选择System.arraycopy

    private static HealthMessage[] join(HealthMessage[] healthMessages1, HealthMessage[] healthMessages2)
    {
        HealthMessage[] healthMessagesAll = new HealthMessage[healthMessages1.length + healthMessages2.length];
    
        System.arraycopy(healthMessages1, 0, healthMessagesAll, 0, healthMessages1.length);
        System.arraycopy(healthMessages2, 0, healthMessagesAll, healthMessages1.length, healthMessages2.length);
    
        return healthMessagesAll;
    }
    

    【讨论】:

      【解决方案5】:

      数组是固定长度的,因此您有多种选择。以下是一对:

      a) 创建一个与其他数组大小相同的新数组并手动复制所有元素。

      healthMessagesAll = new HealthMessage[healthMessages1.length + healthMessages2.length];
      int i = 0;
      for (HealthMessage msg : healthMessases1)
      {
         healthMessagesAll[i] = msg;
         i++;
      }
      
      for (HealthMessage msg : healthMessages2)
      {
         healthMessagesAll[i] = msg;
         i++;
      }
      

      b) 使用Arrays 类提供的方法。您可以将数组转换为列表,或批量复制元素。查看它提供的功能并选择适合您的功能。

      更新

      看到您对重复项的评论。您可能希望将所有内容都放在保证唯一性的Set 中。如果两次添加相同的元素,则不会添加第二次。 然后,如果您明确需要具有自己的 toArray() 方法的数组,则可以将 Set 转换回数组。

      正如其他受访者所建议的,System.arraycopy() 也可以帮助您复制元素的内容,因此它是我上面的替代方案 (a) 的较短版本。

      【讨论】:

        【解决方案6】:

        对于最复杂但最不占用内存的解决方案,您可以将它们包装在一个对象中。这个提供了一个跨越所有项目的Iterator&lt;T&gt; 和一个copyTo 复制到新数组的方法。它可以很容易地增强以提供 getter 和 setter。

        public class JoinedArray<T> implements Iterable<T> {
          final List<T[]> joined;
        
          // Pass all arrays to be joined as constructor parameters.
          public JoinedArray(T[]... arrays) {
            joined = Arrays.asList(arrays);
          }
        
          // Iterate across all entries in all arrays (in sequence).
          public Iterator<T> iterator() {
            return new JoinedIterator<T>(joined);
          }
        
          private class JoinedIterator<T> implements Iterator<T> {
            // The iterator across the arrays.
            Iterator<T[]> i;
            // The array I am working on. Equivalent to i.next without the hassle.
            T[] a;
            // Where we are in it.
            int ai;
            // The next T to return.
            T next = null;
        
            private JoinedIterator(List<T[]> joined) {
              i = joined.iterator();
              a = nextArray();
            }
        
            private T[] nextArray () {
              ai = 0;
              return i.hasNext() ? i.next() : null;
            }
        
            public boolean hasNext() {
              if (next == null) {
                // a goes to null at the end of i.
                if (a != null) {
                  // End of a?
                  if (ai >= a.length) {
                    // Yes! Next i.
                    a = nextArray();
                  }
                  if (a != null) {
                    next = a[ai++];
                  }
                }
              }
              return next != null;
            }
        
            public T next() {
              T n = null;
              if (hasNext()) {
                // Give it to them.
                n = next;
                next = null;
              } else {
                // Not there!!
                throw new NoSuchElementException();
              }
              return n;
            }
        
            public void remove() {
              throw new UnsupportedOperationException("Not supported.");
            }
          }
        
          public int copyTo(T[] to, int offset, int length) {
            int copied = 0;
            // Walk each of my arrays.
            for (T[] a : joined) {
              // All done if nothing left to copy.
              if (length <= 0) {
                break;
              }
              if (offset < a.length) {
                // Copy up to the end or to the limit, whichever is the first.
                int n = Math.min(a.length - offset, length);
                System.arraycopy(a, offset, to, copied, n);
                offset = 0;
                copied += n;
                length -= n;
              } else {
                // Skip this array completely.
                offset -= a.length;
              }
            }
            return copied;
          }
        
          public int copyTo(T[] to, int offset) {
            return copyTo(to, offset, to.length);
          }
        
          public int copyTo(T[] to) {
            return copyTo(to, 0);
          }
        
          @Override
          public String toString() {
            StringBuilder s = new StringBuilder();
            Separator comma = new Separator(",");
            for (T[] a : joined) {
              s.append(comma.sep()).append(Arrays.toString(a));
            }
            return s.toString();
          }
        
          public static void main(String[] args) {
            JoinedArray<String> a = new JoinedArray<String>(
                    new String[]{
                      "One"
                    },
                    new String[]{
                      "Two",
                      "Three",
                      "Four",
                      "Five"
                    },
                    new String[]{
                      "Six",
                      "Seven",
                      "Eight",
                      "Nine"
                    });
            for (String s : a) {
              System.out.println(s);
            }
            String[] four = new String[4];
            int copied = a.copyTo(four, 3, 4);
            System.out.println("Copied " + copied + " = " + Arrays.toString(four));
        
          }
        }
        

        【讨论】:

        • ...很好,但不要忘记单元测试 ;-)
        【解决方案7】:

        沿途有什么事情:

            List<String> l1 = Arrays.asList(healthMessages1);
            l1.addAll(Arrays.asList(healthMessages2));
            HealthMessage[] result = l1.toArray();
        

        (需要一点泛化... :)

        【讨论】:

        • Arrays.asList(T... a) 返回一个固定大小的列表。您将在第二行出现异常。
        猜你喜欢
        • 1970-01-01
        • 2013-06-08
        • 2011-03-06
        • 2019-05-12
        • 2016-12-27
        • 1970-01-01
        • 1970-01-01
        • 2019-12-01
        • 1970-01-01
        相关资源
        最近更新 更多