How to make two arrays having different references?

大憨熊 提交于 2021-02-11 14:52:30

问题


I have to reverse two arrays so that, they both have the same values but different references.

Here is my code so far.

But how to achieve that when both arrays are pointing to the same program arguments?

And why does String[] reference reverse the String[] values instead of reversing the program arguments?

For example. If the program arguments were 1 2 3 4 5:

String[] values = 5 4 3 2 1
String[] reference = 1 2 3 4 5
public static void main(String[] args) {
    String[] values = changeValues(args);
    System.out.println(Arrays.toString(values));
    String[] reference = changeReference(args);
    System.out.println(Arrays.toString(reference));

    if (!testSameValues(values, reference)) {
        System.out.println("Error: Values do not match !");
    }

    if (testSameReference(values, reference)) {
        System.out.println("Error: References are the same !");
    }
}
public static String[] changeValues(String[] x) {
    for (int i = 0; i < x.length / 2; i++) {
        String temp = x[i];
        x[i] = x[(x.length - 1) - i];
        x[(x.length - 1) - i] = temp;
    }
    return x;
}

public static String[] changeReference(String[] y) {
    for (int i = 0; i < y.length / 2; i++) {
        String temp = y[i];
        y[i] = y[(y.length - 1) - i];
        y[(y.length - 1) - i] = temp;
    }
    return y;
}

public static boolean testSameValues(String[] x, String[] y) {
    if (x.equals(y)) {
        return true;
    } else
        return false;
}

public static boolean testSameReference(String[] x, String[] y) {
    if (x == y) {
        return true;
    } else
        return false;
}

回答1:


changeReference and changeValues methods do the same thing - reverse the array. That is why in the end you see the same input array.

To change the reference, you need to create a new array and populate it with the same elements from the original one.

EDIT: copying array into a new one

public static String[] changeReference(String[] y) {
    String[] copy = new String[y.length];
    for(int i = 0; i < y.length; i++) {
        copy[i] = y[i]
    }
    return copy;
}




回答2:


Your reverse method operates on the input array only and creates no new arrays. It's easy enough to write a method that will reverse a String[] and return a new array. Something like

private static String[] copyReverse(String[] arr) {
    String[] ret = new String[arr.length];
    for (int i = 0; i < arr.length; i++) {
        ret[i] = arr[arr.length - i - 1];
    }
    return ret;
}

Then you can call it successively. Like,

String[] values = copyReverse(args);
String[] reference = copyReverse(values);

I think you wanted two methods, one to copy an array and one to reverse an array. Let's make those methods generic, but to generically copy an array we need to pass the class as well. Something like,

private static <T> T[] copy(Class<T> cls, T[] arr) {
    T[] ret = (T[]) Array.newInstance(cls, arr.length);
    for (int i = 0; i < arr.length; i++) {
        ret[i] = arr[i];
    }
    return ret;
}

When reversing an array in place, I find it easier to read if I use two variables for positions in the array. Like,

private static <T> T[] reverse(T[] arr) {
    for (int i = 0, j = arr.length - 1; i < arr.length / 2; i++, j--) {
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    return arr;
}

And to copyReverse generically,

private static <T> T[] copyReverse(Class<T> cls, T[] arr) {
    T[] ret = (T[]) Array.newInstance(cls, arr.length);
    for (int i = 0; i < arr.length; i++) {
        ret[i] = arr[arr.length - i - 1];
    }
    return ret;
}

To copy a String[] you could use either

String[] values = copy(String.class, args);
String[] reversed = copyReverse(String.class, args);

But if you use the inplace reverse it modifies the passed in array.




回答3:


You can simply copy the reversed array and get two different references with the same content:

// original array
String[] arr1 = {"5", "7", "3", "2", "1"};

// reversed array
String[] arr2 = IntStream
        // iterating in reverse order
        .iterate(arr1.length, i -> i > 0, i -> i - 1)
        // get an element by its index
        .mapToObj(i -> arr1[i - 1])
        .toArray(String[]::new);

// copy of the reversed array
String[] arr3 = Arrays.stream(arr2).toArray(String[]::new);
System.out.println(Arrays.toString(arr2)); // [1, 2, 3, 7, 5]
System.out.println(Arrays.toString(arr3)); // [1, 2, 3, 7, 5]

System.out.println(arr2 == arr3); // false
System.out.println(Arrays.equals(arr2, arr3)); // true
System.out.println(Arrays.compare(arr2, arr3)); // 0

See also: Swapping first array element with last, second with second last and so on




回答4:


Clone the array:

String[] values = changeValues(args.clone());
String[] reference = changeReference(args.clone());

Note that since changeValues and changeReference do the same thing, you could just use changeValues for both or changeReference for both. The array's location in memory is based off of the location of the array passed in, not the name of the function.



来源:https://stackoverflow.com/questions/65267922/how-to-make-two-arrays-having-different-references

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!