ChatGPT解决这个技术问题 Extra ChatGPT

How do I reverse an int array in Java?

I am trying to reverse an int array in Java.

This method does not reverse the array.

for(int i = 0; i < validData.length; i++)
{
    int temp = validData[i];
    validData[i] = validData[validData.length - i - 1];
    validData[validData.length - i - 1] = temp;
}

What is wrong with it?

I see what I did wrong. Should be validData.length/2. Otherwise it will reverse itself then un-reverse itself.
See en.wikipedia.org/wiki/In-place_algorithm which contains a description of the correct version of this algorithm.

3
3lectrologos

To reverse an int array, you swap items up until you reach the midpoint, like this:

for(int i = 0; i < validData.length / 2; i++)
{
    int temp = validData[i];
    validData[i] = validData[validData.length - i - 1];
    validData[validData.length - i - 1] = temp;
}

The way you are doing it, you swap each element twice, so the result is the same as the initial list.


And I would like to put validData.length / 2 part to the outside of the for-loop.
@Jin I wouldn't. It only obfuscates the meaning, and I bet the optimizing compiler would do it for you anyway. Regardless, there's no point micro-optimizing until you have clear evidence from profiling that it is necessary/helpful.
@JinKwon That would be sort of like doing validData.length >> 1. That is equivalent and faster, but it confuses many programmers and any good compiler will automatically do that.
You should only do this calculation once validData.length - i - 1 and save it to a variable.
Can any one suggest a reversal with out temp variable !!
M
Manur

With Commons.Lang, you could simply use

ArrayUtils.reverse(int[] array)

Most of the time, it's quicker and more bug-safe to stick with easily available libraries already unit-tested and user-tested when they take care of your problem.


I would have prefererred it returned the reversed (passed) array for functional-like style.
@laurent-g to be fair : to reverse the array this way is more memory efficient, which is probably why they did it this way.
My point was not the copy or not copy. My message states "(passed)" to be returned (after being reversed), so it could be passed in an expression, not needing a separate statement.
What if I don't want to use ArrayUtils? How can you do it manually?
@LaurentG make a helper function private int[] reversed(int[] array) {ArrayUtils.reverse(array);} and then you can do f(reversed(arr)); :))
e
escitalopram
Collections.reverse(Arrays.asList(yourArray));

java.util.Collections.reverse() can reverse java.util.Lists and java.util.Arrays.asList() returns a list that wraps the the specific array you pass to it, therefore yourArray is reversed after the invocation of Collections.reverse().

The cost is just the creation of one List-object and no additional libraries are required.

A similar solution has been presented in the answer of Tarik and their commentors, but I think this answer would be more concise and more easily parsable.


For arrays of objects, this is a good solution. But it doesn't work for arrays of primitives. E. g. passing an int[] to asList(...) will not return a List<Integer>, but a List<int[]>, containing one element. There is AFAICS no simple built-in way to convert an int[] to an Integer[].
This wont work with primitive arrays... collections dosnt return a value so now you have a useless array as a list in memory
@MartinRust Java 8+: Arrays.stream(arr).boxed().collect(Collectors.toList()) or Arrays.stream(arr).boxed().toArray(Integer[]::new)
@KingLogic Well, it's a one-liner and the prettiest thing I could come up with. Feel free to suggest something better (that does not rely upon a library).
W
Willi Mentzel
public class ArrayHandle {
    public static Object[] reverse(Object[] arr) {
        List<Object> list = Arrays.asList(arr);
        Collections.reverse(list);
        return list.toArray();
    }
}

Of course it will. A list can only hold Objects, not primitives, so all the primitives (ints in this case) are wrapped in to their respective wrappers (Integers in this case) and put in the list. You see, Integers are objects. @Tom
Watch out: If I'm not wrong the original array is modified. To make it clear you may want to just not return anything.
@11684 Yes, generic lists can only hold Objects. But the method excepts an array. Arrays can hold primitives. Therefore int[] is different from Integer[]. Try it: Integer[] array = new int[5]. You'll get a compile error. This is why the Java Arrays class defines a bunch of methods for working with primitive arrays. Trying to pass an int[] to the above method will result in something like The method reverse(Object[]) in the type MakeSimple is not applicable for the arguments (int[]). @Filip - an in-place algorithm uses less memory and runs faster.
@Andrea Actually, it isn't. The list returned by Arrays.asList() doesn't reference the original array, nor does the array returned. That's one of the problems with this method: it uses triple the memory and does triple the work as an in-place algorithm.
This method itself might work, but one simply cannot pass an int[] as an argument to this method ("incompatible types: int[] cannot be converted to Object[]").
B
Bill the Lizard

I think it's a little bit easier to follow the logic of the algorithm if you declare explicit variables to keep track of the indices that you're swapping at each iteration of the loop.

public static void reverse(int[] data) {
    for (int left = 0, right = data.length - 1; left < right; left++, right--) {
        // swap the values at the left and right indices
        int temp = data[left];
        data[left]  = data[right];
        data[right] = temp;
    }
}

I also think it's more readable to do this in a while loop.

public static void reverse(int[] data) {
    int left = 0;
    int right = data.length - 1;

    while( left < right ) {
        // swap the values at the left and right indices
        int temp = data[left];
        data[left] = data[right];
        data[right] = temp;

        // move the left and right index pointers in toward the center
        left++;
        right--;
    }
}

old school swap looks more easy but yes when involving array index values left,right,... will be helpful for debugging if any
You could also add 'public static void swap(int[] data, int index1, int index2) { ... }' and use that from 'reverse' like this: swap(data, left, right).
P
Patrick Parker

There are already a lot of answers here, mostly focused on modifying the array in-place. But for the sake of completeness, here is another approach using Java streams to preserve the original array and create a new reversed array:

    int[] a = {8, 6, 7, 5, 3, 0, 9};
    int[] b = IntStream.rangeClosed(1, a.length).map(i -> a[a.length-i]).toArray();

L
Laser Infinite

In case of Java 8 we can also use IntStream to reverse the array of integers as:

int[] sample = new int[]{1,2,3,4,5};
int size = sample.length;
int[] reverseSample = IntStream.range(0,size).map(i -> sample[size-i-1])
                      .toArray(); //Output: [5, 4, 3, 2, 1]

Z
ZhekaKozlov

With Guava:

Collections.reverse(Ints.asList(array));

This is brilliant! Short and effective. Like all asList methods, it creates a view that writes directly through to the backing (primitive) array. I think the down-voter here mistakenly thought that this returned a boxed list or something.
@LukeUsherwood presumably there will still be some overhead from boxing and unboxing when calling get and set on each element. But I agree with you that this is a brilliant solution.
Indeed, that's worth being aware of. I don't think it would be a big deal in the majority of code I personally work with - our 'hot' areas are well defined, the rest is 'glue code' of sorts. At the same time I am concious that memory churn also creates an additional "hidden" cost that profilers don't attribute to the actual function.
@LukeUsherwood it still does return a boxed list instead of a prim array
@AnthonyJClink Not sure what "it" refers to, but the JDK utility Collections.reverse is a void method. This operates in-place on a Guava internal class which wraps an int[] (Since it never stores a list of boxed Integers I wouldn't call the class a "boxed list", but rather a "List view of an array"). But yes it operates via an interface passing Integer objects, so this would create a lot of temporary object churn and boxing as mentioned. Try an IntStream or a primitive-collection library for where performance matters. (Trove, Koloboke, Eclipse Collections, ...)
D
Deepak Singh
for(int i=validData.length-1; i>=0; i--){
  System.out.println(validData[i]);
 }

Unfortunately, this is the most clean answer available here, because every developer will know how to do it and it doesn't require any extended package installs.
This is good for getting the values of the array, but if you really want to reverse the array, you would have to create a new one using this method => the other ones would be more efficient.
T
ThisClark

Simple for loop!

for (int start = 0, end = array.length - 1; start <= end; start++, end--) {
    int aux = array[start];
    array[start]=array[end];
    array[end]=aux;
}

In the future, please let the asker know specifically what they did incorrectly, and what you did correctly.
change start <= end to start < end
R
Radiodef

This will help you

int a[] = {1,2,3,4,5};
for (int k = 0; k < a.length/2; k++) {
    int temp = a[k];
    a[k] = a[a.length-(1+k)];
    a[a.length-(1+k)] = temp;
}

A
AnthonyJClink

This is how I would personally solve it. The reason behind creating the parametrized method is to allow any array to be sorted... not just your integers.

I hope you glean something from it.

@Test
public void reverseTest(){
   Integer[] ints = { 1, 2, 3, 4 };
   Integer[] reversedInts = reverse(ints);

   assert ints[0].equals(reversedInts[3]);
   assert ints[1].equals(reversedInts[2]);
   assert ints[2].equals(reversedInts[1]);
   assert ints[3].equals(reversedInts[0]);

   reverseInPlace(reversedInts);
   assert ints[0].equals(reversedInts[0]);
}

@SuppressWarnings("unchecked")
private static <T> T[] reverse(T[] array) {
    if (array == null) {
        return (T[]) new ArrayList<T>().toArray();
    }
    List<T> copyOfArray = Arrays.asList(Arrays.copyOf(array, array.length));
    Collections.reverse(copyOfArray);
    return copyOfArray.toArray(array);
}

private static <T> T[] reverseInPlace(T[] array) {
    if(array == null) {
        // didn't want two unchecked suppressions
        return reverse(array);
    }

    Collections.reverse(Arrays.asList(array));
    return array;
}

Doesn't solve the original problem using primatives.
There are many ways to convert prims to objects. I always recommend avoiding prims wherever possible in java and I also believe that it should be encouraged.
Converting an array of primitives of unknown length into an array might be a very bad idea, especially if done without realizing it. Java is not Smalltalk. Primitives are part of the language and have their place. It doesn't matter if we don't like them, we must accept them, and use them where appropriate.
You actually don't need to copy the array, just Collections.reverse(asList(arraytoReverse)); return arrayToReverse;. asList is just a wrapper around the array, so the original array is reversed.
A
AbsoluteBlue

If working with data that is more primitive (i.e. char, byte, int, etc) then you can do some fun XOR operations.

public static void reverseArray4(int[] array) {
    int len = array.length;
    for (int i = 0; i < len/2; i++) {
        array[i] = array[i] ^ array[len - i  - 1];
        array[len - i  - 1] = array[i] ^ array[len - i  - 1];
        array[i] = array[i] ^ array[len - i  - 1];
    }
}

f
fastcodejava

Your program will work for only length = 0, 1. You can try :

int i = 0, j = validData.length-1 ; 
while(i < j)
{
     swap(validData, i++, j--);  // code for swap not shown, but easy enough
}

Perhaps you meant swap as pseudo code for an inline swap rather than a method call, but if not that won't work. Java passes by reference so it is not possible to write a swap method for variables.
I meant whatever way you can get v[i] & v[j] to swap. I am aware how method calls work in java. For method, you can do something like swap(v, i++, j--);
Dean, the array validData is an object, passed by reference, so the swap() method will work perfectly.
K
Karan Khanna

There are two ways to have a solution for the problem:

1. Reverse an array in space.

Step 1. Swap the elements at the start and the end index.

Step 2. Increment the start index decrement the end index.

Step 3. Iterate Step 1 and Step 2 till start index < end index

For this, the time complexity will be O(n) and the space complexity will be O(1)

Sample code for reversing an array in space is like:

public static int[] reverseAnArrayInSpace(int[] array) {
    int startIndex = 0;
    int endIndex = array.length - 1;
    while(startIndex < endIndex) {
        int temp = array[endIndex];
        array[endIndex] = array[startIndex];
        array[startIndex] = temp;
        startIndex++;
        endIndex--;
    }
    return array;
}

2. Reverse an array using an auxiliary array.

Step 1. Create a new array of size equal to the given array.

Step 2. Insert elements to the new array starting from the start index, from the given array starting from end index.

For this, the time complexity will be O(n) and the space complexity will be O(n)

Sample code for reversing an array with auxiliary array is like:

public static int[] reverseAnArrayWithAuxiliaryArray(int[] array) {
    int[] reversedArray = new int[array.length];
    for(int index = 0; index < array.length; index++) {
        reversedArray[index] = array[array.length - index -1]; 
    }
    return reversedArray;
}

Also, we can use the Collections API from Java to do this.

The Collections API internally uses the same reverse in space approach.

Sample code for using the Collections API is like:

public static Integer[] reverseAnArrayWithCollections(Integer[] array) {
    List<Integer> arrayList = Arrays.asList(array);
    Collections.reverse(arrayList);
    return arrayList.toArray(array);
}

ס
סטנלי גרונן

There are some great answers above, but this is how I did it:

public static int[] test(int[] arr) {

    int[] output = arr.clone();
    for (int i = arr.length - 1; i > -1; i--) {
        output[i] = arr[arr.length - i - 1];
    }
    return output;
}

N
Nick Strupat

It is most efficient to simply iterate the array backwards.

I'm not sure if Aaron's solution does this vi this call Collections.reverse(list); Does anyone know?


Iterating backwards over the array requires a new array. I like the solution posted above that does the inline reversing without creating a new array.
@Simucal why create a new array? Just iterate it backwards.
s
subinksoman
public void getDSCSort(int[] data){
        for (int left = 0, right = data.length - 1; left < right; left++, right--){
            // swap the values at the left and right indices
            int temp = data[left];
            data[left]  = data[right];
            data[right] = temp;
        }
    }

u
user11016

Solution with o(n) time complexity and o(1) space complexity.

void reverse(int[] array) {
    int start = 0;
    int end = array.length - 1;
    while (start < end) {
        int temp = array[start];
        array[start] = array[end];
        array[end] = temp;
        start++;
        end--;
    }
}

Just FYI, this can be simplified into a complex for loop: for (int start = 0, end = array.length - 1; start < end; start++, end--) { ... }.
U
Udo Held
public void display(){
  String x[]=new String [5];
  for(int i = 4 ; i > = 0 ; i-- ){//runs backwards

    //i is the nums running backwards therefore its printing from       
    //highest element to the lowest(ie the back of the array to the front) as i decrements

    System.out.println(x[i]);
  }
}

yes i have tried the same and clear code along with output is int[] a = {1,3,5,2,6,7}; for(int i = a.length-1;i>=0;i--) {System.out.print(a[i]+" ");}` it will reverse the array from last index to first index
M
Moddl

Wouldn't doing it this way be much more unlikely for mistakes?

    int[] intArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int[] temp = new int[intArray.length];
    for(int i = intArray.length - 1; i > -1; i --){
            temp[intArray.length - i -1] = intArray[i];
    }
    intArray = temp;

v
vikarjramun

Using the XOR solution to avoid the temp variable your code should look like

for(int i = 0; i < validData.length; i++){
    validData[i] = validData[i] ^ validData[validData.length - i - 1];
    validData[validData.length - i - 1] = validData[i] ^ validData[validData.length - i - 1];
    validData[i] = validData[i] ^ validData[validData.length - i - 1];
}

See this link for a better explanation:

http://betterexplained.com/articles/swap-two-variables-using-xor/


S
Sameer Shrestha

2 ways to reverse an Array .

Using For loop and swap the elements till the mid point with time complexity of O(n/2). private static void reverseArray() { int[] array = new int[] { 1, 2, 3, 4, 5, 6 }; for (int i = 0; i < array.length / 2; i++) { int temp = array[i]; int index = array.length - i - 1; array[i] = array[index]; array[index] = temp; } System.out.println(Arrays.toString(array)); } Using built in function (Collections.reverse()) private static void reverseArrayUsingBuiltInFun() { int[] array = new int[] { 1, 2, 3, 4, 5, 6 }; Collections.reverse(Ints.asList(array)); System.out.println(Arrays.toString(array)); } Output : [6, 5, 4, 3, 2, 1]


What is Ints?
@CodingNow it's one of the Guava utility helper classes - see here
K
Kalidindi Prashanth
    public static void main(String args[])    {
        int [] arr = {10, 20, 30, 40, 50}; 
        reverse(arr, arr.length);
    }

    private static void reverse(int[] arr,    int length)    {

        for(int i=length;i>0;i--)    { 
            System.out.println(arr[i-1]); 
        }
    }

M
Mdhar9e

below is the complete program to run in your machine.

public class ReverseArray {
    public static void main(String[] args) {
        int arr[] = new int[] { 10,20,30,50,70 };
        System.out.println("reversing an array:");
        for(int i = 0; i < arr.length / 2; i++){
            int temp = arr[i];
            arr[i] = arr[arr.length - i - 1];
            arr[arr.length - i - 1] = temp;
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }   
    }
}

For programs on matrix using arrays this will be the good source.Go through the link.


R
Radiodef
private static int[] reverse(int[] array){
    int[] reversedArray = new int[array.length];
    for(int i = 0; i < array.length; i++){
        reversedArray[i] = array[array.length - i - 1];
    }
    return reversedArray;
} 

Please consider adding an explanation to your answer. Code-only answers don't explain anything.
c
craftsmannadeem

Here is a simple implementation, to reverse array of any type, plus full/partial support.

import java.util.logging.Logger;

public final class ArrayReverser {
 private static final Logger LOGGER = Logger.getLogger(ArrayReverser.class.getName());

 private ArrayReverser () {

 }

 public static <T> void reverse(T[] seed) {
    reverse(seed, 0, seed.length);
 }

 public static <T> void reverse(T[] seed, int startIndexInclusive, int endIndexExclusive) {
    if (seed == null || seed.length == 0) {
        LOGGER.warning("Nothing to rotate");
    }
    int start = startIndexInclusive < 0 ? 0 : startIndexInclusive;
    int end = Math.min(seed.length, endIndexExclusive) - 1;
    while (start < end) {
        swap(seed, start, end);
        start++;
        end--;
    }
}

 private static <T> void swap(T[] seed, int start, int end) {
    T temp =  seed[start];
    seed[start] = seed[end];
    seed[end] = temp;
 }  

}

Here is the corresponding Unit Test

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.junit.Before;
import org.junit.Test;

public class ArrayReverserTest {
private Integer[] seed;

@Before
public void doBeforeEachTestCase() {
    this.seed = new Integer[]{1,2,3,4,5,6,7,8};
}

@Test
public void wholeArrayReverse() {
    ArrayReverser.<Integer>reverse(seed);
    assertThat(seed[0], is(8));
}

 @Test
 public void partialArrayReverse() {
    ArrayReverser.<Integer>reverse(seed, 1, 5);
    assertThat(seed[1], is(5));
 }
}

S
Simple-Solution

Here is what I've come up with:

// solution 1 - boiler plated 
Integer[] original = {100, 200, 300, 400};
Integer[] reverse = new Integer[original.length];

int lastIdx = original.length -1;
int startIdx = 0;

for (int endIdx = lastIdx; endIdx >= 0; endIdx--, startIdx++)
   reverse[startIdx] = original[endIdx];

System.out.printf("reverse form: %s", Arrays.toString(reverse));

// solution 2 - abstracted 
// convert to list then use Collections static reverse()
List<Integer> l = Arrays.asList(original);
Collections.reverse(l);
System.out.printf("reverse form: %s", l);

Z
Z A Abbasi
static int[] reverseArray(int[] a) {
     int ret[] = new int[a.length];
     for(int i=0, j=a.length-1; i<a.length && j>=0; i++, j--)
         ret[i] = a[j];
     return ret;
}

r
roshan posakya
 public static int[] reverse(int[] array) {

    int j = array.length-1;
    // swap the values at the left and right indices //////
        for(int i=0; i<=j; i++)
        {
             int temp = array[i];
                array[i] = array[j];
                array[j] = temp;
           j--;
        }

         return array;
    }

      public static void main(String []args){
        int[] data = {1,2,3,4,5,6,7,8,9};
        reverse(data);

    }