0

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;
}
Ihab98
  • 19
  • 6

4 Answers4

2

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

Igor Afanasyev
  • 276
  • 2
  • 7
1

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.

Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
  • It's doing the same thing. It reverses the other string instead of reversing the program arguments. in this case, it doesn't have the same reference which is what we want. but it also doesn't have the same values. I couldn't figure out how to fix that. – Ihab98 Dec 12 '20 at 18:34
  • I do not understand what you mean by "the other string". You omitted at least part of `main`, perhaps the problem is in code you have not included. I note you compare `values` and `reference` (**not** `args`). – Elliott Frisch Dec 12 '20 at 18:37
  • I meant that the method you've written actually solves the problem of having the same references But, it reverses the changeValues method which leads to unmatched values. – Ihab98 Dec 12 '20 at 18:55
  • 1
    I have added further examples, and switched to generics. So it works with more than just `String`(s). – Elliott Frisch Dec 13 '20 at 06:03
0

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

-1

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.

Aplet123
  • 33,825
  • 1
  • 29
  • 55