65

I have an array of objects in Java, and I am trying to pull one element to the top and shift the rest down by one.

Assume I have an array of size 10, and I am trying to pull the fifth element. The fifth element goes into position 0 and all elements from 0 to 5 will be shifted down by one.

This algorithm does not properly shift the elements:

Object temp = pool[position];

for (int i = 0; i < position; i++) {                
    array[i+1] = array[i];
}
array[0] = temp;

How do I do it correctly?

3
  • 1
    As @PaulSassik says, if you need to shift, then this is not a good use of an array. Either use a linked list, or use some kind of pointer into the buffer (and yes, you can have something that approximates a pointer in java). Commented Nov 1, 2011 at 18:20
  • 4
    Consider using System.arraycopy(). Commented Jan 16, 2016 at 17:42
  • stackoverflow.com/questions/59713753/… Commented Jan 13, 2020 at 10:49

18 Answers 18

102

Logically it does not work and you should reverse your loop:

for (int i = position-1; i >= 0; i--) {                
    array[i+1] = array[i];
}

Alternatively you can use

System.arraycopy(array, 0, array, 1, position);
Sign up to request clarification or add additional context in comments.

4 Comments

Don't forget to create a new array larger than the original. String[] newArray = new String[myArray.length +1]; System.arraycopy(myArray, 0, newArray, 1, myArray.length);
If performance is an issue, my tests suggest that it's very much faster to overwrite the original array than to use System.arraycopy(). Initialising new arrays seems to be quite expensive.
@Hugo Gresse you don't need to create a temporary copy of the array. See the manual page for arraycopy.
@Tullochgorum System.arraycopy can shift elements and you should not create a new copy of the array. The manual says "If the src and dest arguments refer to the same array object, then the copying is performed as if the components at positions srcPos through srcPos+length-1 were first copied to a temporary array...", the key words in that sentence being "as if".
32

Assuming your array is {10,20,30,40,50,60,70,80,90,100}

What your loop does is:

Iteration 1: array[1] = array[0]; {10,10,30,40,50,60,70,80,90,100}

Iteration 2: array[2] = array[1]; {10,10,10,40,50,60,70,80,90,100}

What you should be doing is

Object temp = pool[position];

for (int i = (position - 1); i >= 0; i--) {                
    array[i+1] = array[i];
}

array[0] = temp;

2 Comments

Obviously it would be better to write for(int i = position; i>0; i--) { array[i] = array[i-1]; }
The difference in generated code is trivial (an extra subtract for (position - 1)) but the clarity and cleanness of position and > instead of (position - 1) and >= is important.
32

You can just use Collections.rotate(List<?> list, int distance)

Use Arrays.asList(array) to convert to List

more info at: https://docs.oracle.com/javase/7/docs/api/java/util/Collections.html#rotate(java.util.List,%20int)

Comments

6

Just for completeness: Stream solution since Java 8.

final String[] shiftedArray = Arrays.stream(array)
        .skip(1)
        .toArray(String[]::new);

I think I sticked with the System.arraycopy() in your situtation. But the best long-term solution might be to convert everything to Immutable Collections (Guava, Vavr), as long as those collections are short-lived.

1 Comment

Doesn't .skip(n) remove the first n elements?
5

Instead of shifting by one position you can make this function more general using module like this.

int[] original = { 1, 2, 3, 4, 5, 6 };
int[] reordered = new int[original.length];
int shift = 1;

for(int i=0; i<original.length;i++)
     reordered[i] = original[(shift+i)%original.length];

5 Comments

Beautiful solution with mod.
failed with this test : original = [3, 8, 9, 7, 6], shift = 3
@AliRezaiyan I just run it with your input and it returns the right value. [3, 8, 9, 7, 6] shift 3 --> [7, 6, 3, 8, 9]
please try with shift 3 this solutions is breaking actual : [2,3,4,5,6,7,1]. expected [5,6,7,1,2,3,4] i guess this solution just work for shift 1
@Lijo i just run it and the result is [5,6,7,1,2,3,4] did you set shift variable to 3?
2

Manipulating arrays in this way is error prone, as you've discovered. A better option may be to use a LinkedList in your situation. With a linked list, and all Java collections, array management is handled internally so you don't have to worry about moving elements around. With a LinkedList you just call remove and then addLast and the you're done.

2 Comments

Yes I know - I chose an Array for some other reasons even though I know its not the best option.
There are many collections to choose from, including generic collections. If you share with us why you needed to use a plain array perhaps we can offer some other alternative suggestions.
1

Try this:

Object temp = pool[position];

for (int i = position-1; i >= 0; i--) {                
    array[i+1] = array[i];
}

array[0] = temp;

Look here to see it working: http://www.ideone.com/5JfAg

1 Comment

@Nayefc: You first copy element 0 to 1. Then you copy the new element 1 to 2. And so on. So basically, apart from index 0, everything has the same value afterwards.
1

Using array Copy Generic solution for k times shift k=1 or k=3 etc

public void rotate(int[] nums, int k) {
            //  Step 1
            // k > array length then we dont need to shift k times because when we shift
            // array length times then the array will go back to intial position.
            // so we can just do only k%array length times.
            // change k = k% array.length;
    
            if (k > nums.length) {
                k = k % nums.length;
            }
            
            //   Step 2;
            // initialize temporary array with same length of input array.
            // copy items from input array starting from array length -k as source till
            // array end and place in new array starting from index 0;
            int[] tempArray = new int[nums.length];
    
            System.arraycopy(nums, nums.length - k, tempArray, 0, k);
            
            //   step3:
            // loop and copy all the remaining elements till array length -k index and copy
            // in result array starting from position k
            for (int i = 0; i < nums.length - k; i++) {
                tempArray[k + i] = nums[i];
            }
            
            // step 4 copy temp array to input array since our goal is to change input
            // array.
    
            System.arraycopy(tempArray, 0, nums, 0, tempArray.length);
    
        }

code

 public void rotate(int[] nums, int k) {
                if (k > nums.length) {
                    k = k % nums.length;
                }
                int[] tempArray = new int[nums.length];
                System.arraycopy(nums, nums.length - k, tempArray, 0, k);
                for (int i = 0; i < nums.length - k; i++) {
                    tempArray[k + i] = nums[i];
                }
                System.arraycopy(tempArray, 0, nums, 0, tempArray.length);
            }

Comments

0

In the first iteration of your loop, you overwrite the value in array[1]. You should go through the indicies in the reverse order.

Comments

0
static void pushZerosToEnd(int arr[])
    {   int n = arr.length;
        int count = 0;  // Count of non-zero elements
        // Traverse the array. If element encountered is non-zero, then
        // replace the element at index 'count' with this element
        for (int i = 0; i < n; i++){
            if (arr[i] != 0)`enter code here`
               // arr[count++] = arr[i]; // here count is incremented
                swapNumbers(arr,count++,i);
        }
        for (int j = 0; j < n; j++){
            System.out.print(arr[j]+",");
        }
     }

    public static void swapNumbers(int [] arr, int pos1, int pos2){
        int temp  = arr[pos2];
        arr[pos2] = arr[pos1];
        arr[pos1] = temp;
    }

Comments

0

Another variation if you have the array data as a Java-List

    listOfStuff.add( 
            0, 
            listOfStuff.remove(listOfStuff.size() - 1) );

Just sharing another option I ran across for this, but I think the answer from @Murat Mustafin is the way to go with a list

Comments

0
public class Test1 {

    public static void main(String[] args) {

        int[] x = { 1, 2, 3, 4, 5, 6 };
        Test1 test = new Test1();
        x = test.shiftArray(x, 2);
        for (int i = 0; i < x.length; i++) {
            System.out.print(x[i] + " ");
        }
    }

    public int[] pushFirstElementToLast(int[] x, int position) {
        int temp = x[0];
        for (int i = 0; i < x.length - 1; i++) {
            x[i] = x[i + 1];
        }
        x[x.length - 1] = temp;
        return x;
    }

    public int[] shiftArray(int[] x, int position) {
        for (int i = position - 1; i >= 0; i--) {
            x = pushFirstElementToLast(x, position);
        }
        return x;
    }
}

2 Comments

You should probably explain your code a bit, also, I don't think this is going to work. Your method pushFirstElementToLast accepts the parameter position, but then doesn't do anything with it... Plus the name of the method suggests that it just moves the first element to the end, instead of inserting it in a specific position.
position variable in that method was unneeded, I accept, but if my code doesn't solve the original problem, plz provide me with the input and the expected output, I will be more than happy to work on it
0

A left rotation operation on an array of size n shifts each of the array's elements unit to the left, check this out!!!!!!

public class Solution {
    private static final Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        String[] nd = scanner.nextLine().split(" ");

        int n = Integer.parseInt(nd[0]);  //no. of elements in the array

        int d = Integer.parseInt(nd[1]);  //number of left rotations

        int[] a = new int[n]; 

      for(int i=0;i<n;i++){
          a[i]=scanner.nextInt();
      }

        Solution s= new Solution();     
//number of left rotations
        for(int j=0;j<d;j++){
              s.rotate(a,n);
        }
   //print the shifted array  
        for(int i:a){System.out.print(i+" ");}
    }

//shift each elements to the left by one 
   public static void rotate(int a[],int n){
            int  temp=a[0];
        for(int i=0;i<n;i++){
            if(i<n-1){a[i]=a[i+1];}
            else{a[i]=temp;}
      }}
}

Comments

0

You can use the Below codes for shifting not rotating:

    int []arr = {1,2,3,4,5,6,7,8,9,10,11,12};
            int n = arr.length;
            int d = 3;

Programm for shifting array of size n by d elements towards left:

    Input : {1,2,3,4,5,6,7,8,9,10,11,12}
    Output: {4,5,6,7,8,9,10,11,12,10,11,12}

        public void shiftLeft(int []arr,int d,int n) {
            for(int i=0;i<n-d;i++) {
                arr[i] = arr[i+d];
            }
        }

Programm for shifting array of size n by d elements towards right:

    Input : {1,2,3,4,5,6,7,8,9,10,11,12}
    Output: {1,2,3,1,2,3,4,5,6,7,8,9}

        public void shiftRight(int []arr,int d,int n) {

            for(int i=n-1;i>=d;i--) {
                arr[i] = arr[i-d];
            }
        }

Comments

0
Left shift in java using java 8


import java.util.*;

class HelloWorld {
    public static void main(String[] args) {
        List<String> list= new ArrayList<>();
        list.add("akash");
        list.add("roopesh");
        list.add("rahul");
        list.add("anubhav");
        System.out.println(list);
        int a=2;
        if(a<=list.size()){
        List<String> resList= new ArrayList<>();
        for(int i=0; i<list.size();i++){
            if(i<list.size()-a){
            resList.add(list.get(i+a));
            }else if(i<list.size()){
                System.out.println(-(list.size()-(i)-a));
            resList.add(list.get(-(list.size()-(i)-a)));
            }
        }
         System.out.println(resList);
       }else{
        System.out.println("Shift value should be less than array size");
      }
    }
}

1 Comment

Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation?
0

This way it would work

public static void rotate(int[] nums) {

    int n = nums.length;
    int temp = nums[n - 1];

    for (int i = n - 1; i >= 0; i--) {
        if (i > 0) {
            nums[i] = nums[i - 1];
        } else {
            nums[i] = temp;
        }
    }
    System.out.println(Arrays.toString(nums));
}

Comments

-1
import java.util.Scanner;

public class Shift {

    public static void main(String[] args) {

        Scanner input = new Scanner (System.in);
        int array[] = new int [5];
        int array1[] = new int [5];
        int i, temp;

        for (i=0; i<5; i++) {
            System.out.printf("Enter array[%d]: \n", i);
            array[i] = input.nextInt(); //Taking input in the array
        }

        System.out.println("\nEntered datas are: \n");
        for (i=0; i<5; i++) {
            System.out.printf("array[%d] = %d\n", i, array[i]); //This will show the data you entered (Not the shifting one)
        }

        temp = array[4]; //We declared the variable "temp" and put the last number of the array there...

        System.out.println("\nAfter Shifting: \n");

        for(i=3; i>=0; i--) {
            array1[i+1] = array[i]; //New array is "array1" & Old array is "array". When array[4] then the value of array[3] will be assigned in it and this goes on..
            array1[0] = temp; //Finally the value of last array which was assigned in temp goes to the first of the new array
        }


        for (i=0; i<5; i++) {
            System.out.printf("array[%d] = %d\n", i, array1[i]);
        }

        input.close();

    }

}

2 Comments

You should add some comments how your code solves the problem.
The OP doesn't want to create a new array. Anyway, you can just use System.arraycopy to do all of this.
-1

Write a Java program to create an array of 20 integers, and then implement the process of shifting the array to right for two elements.

public class NewClass3 {
    
     public static void main (String args[]){
     
     int a [] = {1,2,};
    
     int temp ;
     
     for(int i = 0; i<a.length -1; i++){
      
         temp = a[i];
         a[i] = a[i+1];
         a[i+1] = temp;
     
     }
     
     for(int p : a)
     System.out.print(p);
     }
    
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.