如果数组有效,如何创建传递的数组的深层副本?

时间:2016-09-11 06:05:17

标签: java arrays

因此,IPv4数组被传递给此方法,如果有效,则在实例变量中创建数组的深层副本" parts"

/**
 * If the ip address from the array passed (data) is valid,
 * makes a deep copy of the array passed in the instance variable parts.
 * For example, if data = {192,168,0,1}, parts should become {192,168,0,1}
 * by copying each item of data into corresponding item in parts.
 * If the ip address passed is invalid (for example {500,4,60,216}
 * or {192,16,01}, or {13,13,13,13,13}, parts should become {0,0,0,0}
 * 
 * remember to reset the instance array parts before you do anything else
 * @param data
 */
public void setParts(int[] data) {
this.parts = new int[4];
if (data.length != 4){
    parts = new int[]{0,0,0,0};
}
else
    for (int i = 0; i <= data.length; i++)
        if ((data[i] < 0) || (data[i] > 255))
            parts = new int[]{0,0,0,0};
        else
            parts[i] = data[i];
}
到目前为止,我已经完成了所有工作。我能错过什么?

编辑:做了一个简单的改变:

for (int i = 0; i <= data.length; i++)

for (int i = 0; i < data.length; i++)

和JUnit测试

    public void testSetPartsIntArray() {
    correct1.setParts(new int[]{12, 14, 16, 18});
    int[] a = correct1.getParts();
    assertEquals(4, a.length);
    assertEquals(12, a[0]);
    assertEquals(14, a[1]);
    assertEquals(16, a[2]);
    assertEquals(18, a[3]); 

    correct1.setParts(new int[]{-12, 14, 16, 18});
    a = correct1.getParts();
    assertEquals(4, a.length);
    assertEquals(0, a[0]);
    assertEquals(0, a[1]);
    assertEquals(0, a[2]);
    assertEquals(0, a[3]);  

工作UNTIL

assertEquals(0, a[1]);

是什么导致它停在那里?

2 个答案:

答案 0 :(得分:5)

一旦找到无效值,就必须从循环中断开:

for (int i = 0; i <= data.length; i++)
    if ((data[i] < 0) || (data[i] > 255)) {
        parts = new int[]{0,0,0,0};
        break;
    } else {
        parts[i] = data[i];
    }

在您失败的情况下,第一个元素-12无效,因此parts设置为new int[]{0,0,0,0},但随后您继续循环,因为其余数字有效,最终得到的是{0, 14, 16, 18},而不是{0, 0, 0, 0}

答案 1 :(得分:2)

Eran解决了您的直接问题,但请注意:您仍在使用错误的抽象,并且应围绕以下方面改进您的设计:

  1. 使用int数组来表示IP地址。为此目的,Java有INetAddress。使用4个成员的数组来表示该信息时,有没有的意义。你看,你正在限制自己使用IPv4。 4个整数不会用于IPv6。因此,当有人要求您使用IPv6时,您必须抛弃所有这些!
  2. 你正在混淆责任。似乎setParts()用于在类中设置字段 parts 。但实际上,该方法会执行 valide input 设置。更糟糕的是:如果收到的地址无效,你就不会注意到。那么,你将数组元素重写为全0,但由0.0.0.0产生的地址仍然无效!因此,您需要在所有地方进行检查,以确保您的地址确实有效。不要这样做。最好是A)单独验证您的字段设置输入和B)不允许您的字段部分表示无效的IP地址。
  3. 你看,如果你要使用INetAddress类,那么你将传递一个带有&#34;无效&#34;的字符串。地址;该类会引发异常。这实际上是更好而不是默默地将某些东西变成0.0.0.0。

    因为没有充分的理由说&#34;这里的东西意味着X;但是,为了方便起见,我们也允许它意味着破坏X&#39;&#34;。简单地说:不要这样做。当您不允许&#34;无效时,您的应用程序会变得更强大 要挂起的数据。否则,如上所述;处理部件的每一段代码都必须准备好它是0.0.0.0。所以你需要对它进行错误处理......到处都是!

    最后:如果某处有拼写错误怎么办?有人想传递128.192.168.1,但键入128.912.168.1。难道不应该告诉用户他提供了意想不到的输入吗?!