Skip to content

Commit

Permalink
Add rotate() methods for other primitive array types, except `boole…
Browse files Browse the repository at this point in the history
…an`.

Also add an explanation of possible alternative algorithms, in `Ints.rotate`.

RELNOTES=`primitives`: Added `rotate()` for arrays of all primitive types.
PiperOrigin-RevId: 446428068
  • Loading branch information
eamonnmcmanus authored and Google Java Core Libraries committed May 4, 2022
1 parent f2bb171 commit 6e9057d
Show file tree
Hide file tree
Showing 32 changed files with 2,582 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public void testStatsNoops() {
assertThat(map).containsEntry(three, one);
assertThat(map).containsEntry(one, two);

// TODO(user): Confirm with fry@ that this is a reasonable substitute.
// TODO(cgruber): Confirm with fry@ that this is a reasonable substitute.
// Set<Entry<Object, Object>> entries = map.entrySet();
// assertThat(entries).containsExactly(
// Maps.immutableEntry(three, one), Maps.immutableEntry(one, two));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,237 @@ public void testReverseIndexed() {
new boolean[] {true, true, false, false}, 1, 3, new boolean[] {true, false, true, false});
}

private static void testRotate(boolean[] input, int distance, boolean[] expectedOutput) {
input = Arrays.copyOf(input, input.length);
Booleans.rotate(input, distance);
assertThat(input).isEqualTo(expectedOutput);
}

private static void testRotate(
boolean[] input, int distance, int fromIndex, int toIndex, boolean[] expectedOutput) {
input = Arrays.copyOf(input, input.length);
Booleans.rotate(input, distance, fromIndex, toIndex);
assertThat(input).isEqualTo(expectedOutput);
}

public void testRotate() {
testRotate(new boolean[] {}, -1, new boolean[] {});
testRotate(new boolean[] {}, 0, new boolean[] {});
testRotate(new boolean[] {}, 1, new boolean[] {});

testRotate(new boolean[] {true}, -2, new boolean[] {true});
testRotate(new boolean[] {true}, -1, new boolean[] {true});
testRotate(new boolean[] {true}, 0, new boolean[] {true});
testRotate(new boolean[] {true}, 1, new boolean[] {true});
testRotate(new boolean[] {true}, 2, new boolean[] {true});

testRotate(new boolean[] {true, false}, -3, new boolean[] {false, true});
testRotate(new boolean[] {true, false}, -1, new boolean[] {false, true});
testRotate(new boolean[] {true, false}, -2, new boolean[] {true, false});
testRotate(new boolean[] {true, false}, 0, new boolean[] {true, false});
testRotate(new boolean[] {true, false}, 1, new boolean[] {false, true});
testRotate(new boolean[] {true, false}, 2, new boolean[] {true, false});
testRotate(new boolean[] {true, false}, 3, new boolean[] {false, true});

testRotate(new boolean[] {true, false, true}, -5, new boolean[] {true, true, false});
testRotate(new boolean[] {true, false, true}, -4, new boolean[] {false, true, true});
testRotate(new boolean[] {true, false, true}, -3, new boolean[] {true, false, true});
testRotate(new boolean[] {true, false, true}, -2, new boolean[] {true, true, false});
testRotate(new boolean[] {true, false, true}, -1, new boolean[] {false, true, true});
testRotate(new boolean[] {true, false, true}, 0, new boolean[] {true, false, true});
testRotate(new boolean[] {true, false, true}, 1, new boolean[] {true, true, false});
testRotate(new boolean[] {true, false, true}, 2, new boolean[] {false, true, true});
testRotate(new boolean[] {true, false, true}, 3, new boolean[] {true, false, true});
testRotate(new boolean[] {true, false, true}, 4, new boolean[] {true, true, false});
testRotate(new boolean[] {true, false, true}, 5, new boolean[] {false, true, true});

testRotate(
new boolean[] {true, false, true, false}, -9, new boolean[] {false, true, false, true});
testRotate(
new boolean[] {true, false, true, false}, -5, new boolean[] {false, true, false, true});
testRotate(
new boolean[] {true, false, true, false}, -1, new boolean[] {false, true, false, true});
testRotate(
new boolean[] {true, false, true, false}, 0, new boolean[] {true, false, true, false});
testRotate(
new boolean[] {true, false, true, false}, 1, new boolean[] {false, true, false, true});
testRotate(
new boolean[] {true, false, true, false}, 5, new boolean[] {false, true, false, true});
testRotate(
new boolean[] {true, false, true, false}, 9, new boolean[] {false, true, false, true});

testRotate(
new boolean[] {true, false, true, false, true},
-6,
new boolean[] {false, true, false, true, true});
testRotate(
new boolean[] {true, false, true, false, true},
-4,
new boolean[] {true, true, false, true, false});
testRotate(
new boolean[] {true, false, true, false, true},
-3,
new boolean[] {false, true, true, false, true});
testRotate(
new boolean[] {true, false, true, false, true},
-1,
new boolean[] {false, true, false, true, true});
testRotate(
new boolean[] {true, false, true, false, true},
0,
new boolean[] {true, false, true, false, true});
testRotate(
new boolean[] {true, false, true, false, true},
1,
new boolean[] {true, true, false, true, false});
testRotate(
new boolean[] {true, false, true, false, true},
3,
new boolean[] {true, false, true, true, false});
testRotate(
new boolean[] {true, false, true, false, true},
4,
new boolean[] {false, true, false, true, true});
testRotate(
new boolean[] {true, false, true, false, true},
6,
new boolean[] {true, true, false, true, false});
}

public void testRotateIndexed() {
testRotate(new boolean[] {}, 0, 0, 0, new boolean[] {});

testRotate(new boolean[] {true}, 0, 0, 1, new boolean[] {true});
testRotate(new boolean[] {true}, 1, 0, 1, new boolean[] {true});
testRotate(new boolean[] {true}, 1, 1, 1, new boolean[] {true});

// Rotate the central 5 elements, leaving the ends as-is
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-6,
1,
6,
new boolean[] {false, false, true, false, true, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-1,
1,
6,
new boolean[] {false, false, true, false, true, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
0,
1,
6,
new boolean[] {false, true, false, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
5,
1,
6,
new boolean[] {false, true, false, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
14,
1,
6,
new boolean[] {false, false, true, false, true, true, false});

// Rotate the first three elements
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-2,
0,
3,
new boolean[] {false, false, true, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-1,
0,
3,
new boolean[] {true, false, false, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
0,
0,
3,
new boolean[] {false, true, false, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
1,
0,
3,
new boolean[] {false, false, true, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
2,
0,
3,
new boolean[] {true, false, false, true, false, true, false});

// Rotate the last four elements
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-6,
3,
7,
new boolean[] {false, true, false, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-5,
3,
7,
new boolean[] {false, true, false, false, true, false, true});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-4,
3,
7,
new boolean[] {false, true, false, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-3,
3,
7,
new boolean[] {false, true, false, false, true, false, true});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-2,
3,
7,
new boolean[] {false, true, false, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
-1,
3,
7,
new boolean[] {false, true, false, false, true, false, true});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
0,
3,
7,
new boolean[] {false, true, false, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
1,
3,
7,
new boolean[] {false, true, false, false, true, false, true});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
2,
3,
7,
new boolean[] {false, true, false, true, false, true, false});
testRotate(
new boolean[] {false, true, false, true, false, true, false},
3,
3,
7,
new boolean[] {false, true, false, false, true, false, true});
}

public void testToArray() {
// need explicit type parameter to avoid javac warning!?
List<Boolean> none = Arrays.<Boolean>asList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,103 @@ public void testReverseIndexed() {
testReverse(new byte[] {-1, 1, -2, 2}, 1, 3, new byte[] {-1, -2, 1, 2});
}

private static void testRotate(byte[] input, int distance, byte[] expectedOutput) {
input = Arrays.copyOf(input, input.length);
Bytes.rotate(input, distance);
assertThat(input).isEqualTo(expectedOutput);
}

private static void testRotate(
byte[] input, int distance, int fromIndex, int toIndex, byte[] expectedOutput) {
input = Arrays.copyOf(input, input.length);
Bytes.rotate(input, distance, fromIndex, toIndex);
assertThat(input).isEqualTo(expectedOutput);
}

public void testRotate() {
testRotate(new byte[] {}, -1, new byte[] {});
testRotate(new byte[] {}, 0, new byte[] {});
testRotate(new byte[] {}, 1, new byte[] {});

testRotate(new byte[] {1}, -2, new byte[] {1});
testRotate(new byte[] {1}, -1, new byte[] {1});
testRotate(new byte[] {1}, 0, new byte[] {1});
testRotate(new byte[] {1}, 1, new byte[] {1});
testRotate(new byte[] {1}, 2, new byte[] {1});

testRotate(new byte[] {1, 2}, -3, new byte[] {2, 1});
testRotate(new byte[] {1, 2}, -1, new byte[] {2, 1});
testRotate(new byte[] {1, 2}, -2, new byte[] {1, 2});
testRotate(new byte[] {1, 2}, 0, new byte[] {1, 2});
testRotate(new byte[] {1, 2}, 1, new byte[] {2, 1});
testRotate(new byte[] {1, 2}, 2, new byte[] {1, 2});
testRotate(new byte[] {1, 2}, 3, new byte[] {2, 1});

testRotate(new byte[] {1, 2, 3}, -5, new byte[] {3, 1, 2});
testRotate(new byte[] {1, 2, 3}, -4, new byte[] {2, 3, 1});
testRotate(new byte[] {1, 2, 3}, -3, new byte[] {1, 2, 3});
testRotate(new byte[] {1, 2, 3}, -2, new byte[] {3, 1, 2});
testRotate(new byte[] {1, 2, 3}, -1, new byte[] {2, 3, 1});
testRotate(new byte[] {1, 2, 3}, 0, new byte[] {1, 2, 3});
testRotate(new byte[] {1, 2, 3}, 1, new byte[] {3, 1, 2});
testRotate(new byte[] {1, 2, 3}, 2, new byte[] {2, 3, 1});
testRotate(new byte[] {1, 2, 3}, 3, new byte[] {1, 2, 3});
testRotate(new byte[] {1, 2, 3}, 4, new byte[] {3, 1, 2});
testRotate(new byte[] {1, 2, 3}, 5, new byte[] {2, 3, 1});

testRotate(new byte[] {1, 2, 3, 4}, -9, new byte[] {2, 3, 4, 1});
testRotate(new byte[] {1, 2, 3, 4}, -5, new byte[] {2, 3, 4, 1});
testRotate(new byte[] {1, 2, 3, 4}, -1, new byte[] {2, 3, 4, 1});
testRotate(new byte[] {1, 2, 3, 4}, 0, new byte[] {1, 2, 3, 4});
testRotate(new byte[] {1, 2, 3, 4}, 1, new byte[] {4, 1, 2, 3});
testRotate(new byte[] {1, 2, 3, 4}, 5, new byte[] {4, 1, 2, 3});
testRotate(new byte[] {1, 2, 3, 4}, 9, new byte[] {4, 1, 2, 3});

testRotate(new byte[] {1, 2, 3, 4, 5}, -6, new byte[] {2, 3, 4, 5, 1});
testRotate(new byte[] {1, 2, 3, 4, 5}, -4, new byte[] {5, 1, 2, 3, 4});
testRotate(new byte[] {1, 2, 3, 4, 5}, -3, new byte[] {4, 5, 1, 2, 3});
testRotate(new byte[] {1, 2, 3, 4, 5}, -1, new byte[] {2, 3, 4, 5, 1});
testRotate(new byte[] {1, 2, 3, 4, 5}, 0, new byte[] {1, 2, 3, 4, 5});
testRotate(new byte[] {1, 2, 3, 4, 5}, 1, new byte[] {5, 1, 2, 3, 4});
testRotate(new byte[] {1, 2, 3, 4, 5}, 3, new byte[] {3, 4, 5, 1, 2});
testRotate(new byte[] {1, 2, 3, 4, 5}, 4, new byte[] {2, 3, 4, 5, 1});
testRotate(new byte[] {1, 2, 3, 4, 5}, 6, new byte[] {5, 1, 2, 3, 4});
}

public void testRotateIndexed() {
testRotate(new byte[] {}, 0, 0, 0, new byte[] {});

testRotate(new byte[] {1}, 0, 0, 1, new byte[] {1});
testRotate(new byte[] {1}, 1, 0, 1, new byte[] {1});
testRotate(new byte[] {1}, 1, 1, 1, new byte[] {1});

// Rotate the central 5 elements, leaving the ends as-is
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -6, 1, 6, new byte[] {0, 2, 3, 4, 5, 1, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -1, 1, 6, new byte[] {0, 2, 3, 4, 5, 1, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 0, 1, 6, new byte[] {0, 1, 2, 3, 4, 5, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 5, 1, 6, new byte[] {0, 1, 2, 3, 4, 5, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 14, 1, 6, new byte[] {0, 2, 3, 4, 5, 1, 6});

// Rotate the first three elements
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -2, 0, 3, new byte[] {2, 0, 1, 3, 4, 5, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -1, 0, 3, new byte[] {1, 2, 0, 3, 4, 5, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 0, 0, 3, new byte[] {0, 1, 2, 3, 4, 5, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 1, 0, 3, new byte[] {2, 0, 1, 3, 4, 5, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 2, 0, 3, new byte[] {1, 2, 0, 3, 4, 5, 6});

// Rotate the last four elements
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -6, 3, 7, new byte[] {0, 1, 2, 5, 6, 3, 4});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -5, 3, 7, new byte[] {0, 1, 2, 4, 5, 6, 3});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -4, 3, 7, new byte[] {0, 1, 2, 3, 4, 5, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -3, 3, 7, new byte[] {0, 1, 2, 6, 3, 4, 5});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -2, 3, 7, new byte[] {0, 1, 2, 5, 6, 3, 4});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, -1, 3, 7, new byte[] {0, 1, 2, 4, 5, 6, 3});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 0, 3, 7, new byte[] {0, 1, 2, 3, 4, 5, 6});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 1, 3, 7, new byte[] {0, 1, 2, 6, 3, 4, 5});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 2, 3, 7, new byte[] {0, 1, 2, 5, 6, 3, 4});
testRotate(new byte[] {0, 1, 2, 3, 4, 5, 6}, 3, 3, 7, new byte[] {0, 1, 2, 4, 5, 6, 3});
}

@GwtIncompatible // NullPointerTester
public void testNulls() {
new NullPointerTester().testAllPublicStaticMethods(Bytes.class);
Expand Down
Loading

0 comments on commit 6e9057d

Please sign in to comment.