简体   繁体   中英

Shifting an array

I see this code on a book that its job is array shifting.

public void arrayshift(int count) {
    synchronized (array) {
        System.arraycopy(array, count, array, 0, array.length - count);
    }
}

Now I run this code like down, but the result is wrong!

public class t2 {

static byte array[] = new byte[]{1, 2, 3, 4, 5, 6};

public void arrayshift(int count) {
    synchronized (array) {
        System.arraycopy(array, count, array, 0, array.length - count);
    }
}

public static void main(String[] args) {
    System.out.println("First array: " + Arrays.toString(array));
    new t2().arrayshift(2);
    System.out.println("After two shift is: " + Arrays.toString(array));
   }
}

Result:

First array: [1, 2, 3, 4, 5, 6]
After two shift is: [3, 4, 5, 6, 5, 6]

To actually rotate there is an alternative way, by using Collections.rotate()

In your case, you can convert byte[] to Byte[] , create a list of Bytes and rotate using Collections.rotate()

Below is a quick and dirty way of doing it, staying close to what you've done.

Your modified code:

static byte array[] = new byte[] { 1, 2, 3, 4, 5, 6 };
    static List<Byte> list = new ArrayList<Byte>();

    public static void main(String[] args) {
        System.out.println("First array: " + Arrays.toString(array));
        new Rotate().arrayshift(2);
        System.out.println("After two shift is: ");
        for (Byte b : list.toArray(new Byte[list.size()]))
            System.out.print(b.byteValue() + ", ");
    }

    public void arrayshift(int count) {
        synchronized (array) {
            Byte[] byteObjects = new Byte[array.length];
            int i = 0;
            for (byte b : array)
                byteObjects[i++] = b;
            list = Arrays.asList(byteObjects);
            Collections.rotate(list, count);
        }
    }

Output:

First array: [1, 2, 3, 4, 5, 6]
After two shift is: 
5, 6, 1, 2, 3, 4, 

The results are correct.

System.arraycopy(array, count, array, 0, array.length - count);

The parameters for the function are:

Object src,
int srcPos,
Object dest,
int destPos,
int length

So you are taking from array[2] onward (so 3, 4, 5, 6), you are taking array.length (6) - count (2) so 4 items (so [3, 4, 5, 6]) and you are copying them to array[0]. This will overwrite the first 4 items of the array with your [3,4,5,6], so you'll have [3,4,5,6,5,6]. Notice that you never did anything with the last two values. This is just shiftig the values, not rotating them. If you wanted to rotate them you'd have to save the values that you were going to overwrite and then write them at the end.

It looks to be correct because the System.arraycopy takes 5 parameters as:

  1. Source array : array in your case
  2. Source position: in your case 2, ie the 3rd element.
  3. Destination array: array in your case, source and destination array are same in ur case.
  4. Destination position: in your case, ie start of the array.
  5. Length: how many elements to move, 6-2=4, ie move from 3rd, 4th, 5th, 6th element to 0th, 1st, 2nd, 3rd, so 5th and 6th are not changed.

It looks to be doing the correct shift.

See the docs .

public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

It'll copy {length} number of elements. In your code you are copying array.length-count which means you are copying only 4 elements. Last two element are not copied from source. So the source value stays.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM