From ac66e33bf3501e92b73dac88b3645a06571d4875 Mon Sep 17 00:00:00 2001 From: Gregor Billing Date: Wed, 16 Nov 2022 19:03:52 +0900 Subject: [PATCH] Migrate to Java 8 language level (#42) * Lift language level to Java 8 * Migrate Java 8 language features * General code cleanup * Bump dependency versions compatible with Java 8 --- .../main/kotlin/configurations/Languages.kt | 2 +- gradle/libs.versions.toml | 6 +- .../scrambleanalysis/ScrambleProvider.java | 6 +- .../scrambleanalysis/CubeTestTest.java | 2 +- .../tnoodle/puzzle/ClockPuzzle.java | 37 ++++---- .../tnoodle/puzzle/CubePuzzle.java | 42 ++++----- .../tnoodle/puzzle/FourByFourCubePuzzle.java | 12 ++- .../tnoodle/puzzle/MegaminxPuzzle.java | 70 +++++++-------- .../tnoodle/puzzle/PyraminxPuzzle.java | 20 ++--- .../tnoodle/puzzle/SkewbPuzzle.java | 28 +++--- .../tnoodle/puzzle/SkewbSolver.java | 7 +- .../tnoodle/puzzle/SquareOnePuzzle.java | 40 ++++----- .../puzzle/ThreeByThreeCubePuzzle.java | 10 +-- .../tnoodle/puzzle/TwoByTwoCubePuzzle.java | 5 +- .../tnoodle/puzzle/TwoByTwoSolver.java | 4 +- .../tnoodle/scrambles/AlgorithmBuilder.java | 22 ++--- .../scrambles/InvalidMoveException.java | 1 - .../scrambles/InvalidScrambleException.java | 1 - .../tnoodle/scrambles/LazySupplier.java | 9 +- .../tnoodle/scrambles/Puzzle.java | 74 ++++++++-------- .../tnoodle/scrambles/PuzzleImageInfo.java | 11 +-- .../tnoodle/scrambles/PuzzleRegistry.java | 4 +- .../tnoodle/scrambles/ScrambleCacher.java | 85 +++++++++---------- .../tnoodle/HugeScrambleTest.java | 21 ++--- .../puzzle/NoInspectionThreeByThreeTest.java | 6 +- .../ThreeByThreeCubeFewestMovesTest.java | 6 +- .../tnoodle/svglite/Element.java | 30 ++++--- .../svglite/InvalidHexColorException.java | 1 - .../tnoodle/svglite/Path.java | 18 ++-- .../tnoodle/svglite/PathIterator.java | 4 +- 30 files changed, 273 insertions(+), 311 deletions(-) diff --git a/buildSrc/src/main/kotlin/configurations/Languages.kt b/buildSrc/src/main/kotlin/configurations/Languages.kt index 1e027669..967a8241 100644 --- a/buildSrc/src/main/kotlin/configurations/Languages.kt +++ b/buildSrc/src/main/kotlin/configurations/Languages.kt @@ -17,7 +17,7 @@ object Languages { fun Project.configureJava() { configure { - sourceCompatibility = JavaVersion.VERSION_1_6 + sourceCompatibility = JavaVersion.VERSION_1_8 withJavadocJar() withSourcesJar() diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 345643c1..774ee0a7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,8 +1,8 @@ [versions] -junit-jupiter = "5.5.2" +junit-jupiter = "5.9.1" [libraries] -logback-classic = { module = "ch.qos.logback:logback-classic", version = "1.2.10" } +logback-classic = { module = "ch.qos.logback:logback-classic", version = "1.4.4" } gwt-exporter = { module = "org.timepedia.exporter:gwtexporter", version = "2.5.1" } junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit-jupiter" } junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit-jupiter" } @@ -10,5 +10,5 @@ apache-commons-math3 = { module = "org.apache.commons:commons-math3", version = [plugins] shadow = { id = "com.github.johnrengelman.shadow", version = "7.1.2" } -dependency-versions = { id = "com.github.ben-manes.versions", version = "0.42.0" } +dependency-versions = { id = "com.github.ben-manes.versions", version = "0.44.0" } nexus-publish = { id = "io.github.gradle-nexus.publish-plugin", version = "1.1.0" } diff --git a/scrambleanalysis/src/main/java/org/worldcubeassociation/tnoodle/scrambleanalysis/ScrambleProvider.java b/scrambleanalysis/src/main/java/org/worldcubeassociation/tnoodle/scrambleanalysis/ScrambleProvider.java index 3253926f..b933ec8b 100644 --- a/scrambleanalysis/src/main/java/org/worldcubeassociation/tnoodle/scrambleanalysis/ScrambleProvider.java +++ b/scrambleanalysis/src/main/java/org/worldcubeassociation/tnoodle/scrambleanalysis/ScrambleProvider.java @@ -13,7 +13,7 @@ public class ScrambleProvider { public static List getScrambles(String fileName) throws IOException { - List scrambles = new ArrayList(); + List scrambles = new ArrayList<>(); // Read scrambles File file = new File(fileName); @@ -37,7 +37,7 @@ public static List getScrambles(String fileName) throws IOException { // This is the main test public static List generateWcaScrambles(CubePuzzle cube, int N) { - List scrambles = new ArrayList(N); + List scrambles = new ArrayList<>(N); for (int i = 0; i < N; i++) { // Give some status to the user @@ -59,7 +59,7 @@ public static List generateWcaScrambles(int N) { } public static List convertToCubeStates(List scrambles) throws InvalidScrambleException { - List cubeStates = new ArrayList(scrambles.size()); + List cubeStates = new ArrayList<>(scrambles.size()); CubePuzzle puzzle = new CubePuzzle(3); for (String scramble : scrambles) { diff --git a/scrambleanalysis/src/test/java/org/worldcubeassociation/tnoodle/scrambleanalysis/CubeTestTest.java b/scrambleanalysis/src/test/java/org/worldcubeassociation/tnoodle/scrambleanalysis/CubeTestTest.java index 449481b1..2bec48a8 100644 --- a/scrambleanalysis/src/test/java/org/worldcubeassociation/tnoodle/scrambleanalysis/CubeTestTest.java +++ b/scrambleanalysis/src/test/java/org/worldcubeassociation/tnoodle/scrambleanalysis/CubeTestTest.java @@ -27,7 +27,7 @@ public void test() throws Exception { } private List randomMovesScrambles(int N) { - List result = new ArrayList(); + List result = new ArrayList<>(); for (int i = 0; i < N; i++) { result.add(randomMovesScramble()); } diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/ClockPuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/ClockPuzzle.java index 72b784e7..0c22bd38 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/ClockPuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/ClockPuzzle.java @@ -2,10 +2,7 @@ import org.worldcubeassociation.tnoodle.svglite.*; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Random; +import java.util.*; import java.util.logging.Logger; import org.worldcubeassociation.tnoodle.scrambles.InvalidScrambleException; @@ -55,7 +52,7 @@ public String getShortName() { {1,1,1,1,1,1,1,1,1, -1, 0,-1, 0, 0, 0,-1, 0,-1},// A }; - private static HashMap defaultColorScheme = new HashMap(); + private static final Map defaultColorScheme = new HashMap<>(); static { defaultColorScheme.put("Front", new Color(0x3375b2)); defaultColorScheme.put("Back", new Color(0x55ccff)); @@ -67,8 +64,8 @@ public String getShortName() { defaultColorScheme.put("PinDown", new Color(0x885500)); } @Override - public HashMap getDefaultColorScheme() { - return new HashMap(defaultColorScheme); + public Map getDefaultColorScheme() { + return new HashMap<>(defaultColorScheme); } @Override @@ -94,20 +91,20 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { int turn = r.nextInt(12)-5; boolean clockwise = ( turn >= 0 ); turn = Math.abs(turn); - scramble.append( turns[x] + turn + (clockwise?"+":"-") + " "); + scramble.append(turns[x]).append(turn).append(clockwise ? "+" : "-").append(" "); } scramble.append( "y2 "); for(int x=4; x<9; x++) { int turn = r.nextInt(12)-5; boolean clockwise = ( turn >= 0 ); turn = Math.abs(turn); - scramble.append( turns[x] + turn + (clockwise?"+":"-") + " "); + scramble.append(turns[x]).append(turn).append(clockwise ? "+" : "-").append(" "); } boolean isFirst = true; for(int x=0;x<4;x++) { if (r.nextInt(2) == 1) { - scramble.append((isFirst?"":" ")+turns[x]); + scramble.append(isFirst ? "" : " ").append(turns[x]); isFirst = false; } } @@ -125,9 +122,9 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { public class ClockState extends PuzzleState { - private boolean[] pins; - private int[] posit; - private boolean rightSideUp; + private final boolean[] pins; + private final int[] posit; + private final boolean rightSideUp; public ClockState() { pins = new boolean[] {false, false, false, false}; posit = new int[] {0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0}; @@ -141,8 +138,8 @@ public ClockState(boolean[] pins, int[] posit, boolean rightSideUp) { } @Override - public LinkedHashMap getSuccessorsByName() { - LinkedHashMap successors = new LinkedHashMap(); + public Map getSuccessorsByName() { + Map successors = new LinkedHashMap<>(); for(int turn = 0; turn < turns.length; turn++) { for(int rot = 0; rot < 12; rot++) { @@ -197,7 +194,7 @@ public int hashCode() { } @Override - protected Svg drawScramble(HashMap colorScheme) { + protected Svg drawScramble(Map colorScheme) { Svg svg = new Svg(getPreferredSize()); svg.setStroke(STROKE_WIDTH, 10, "round"); drawBackground(svg, colorScheme); @@ -210,7 +207,7 @@ protected Svg drawScramble(HashMap colorScheme) { return svg; } - protected void drawBackground(Svg g, HashMap colorScheme) { + protected void drawBackground(Svg g, Map colorScheme) { String[] colorString; if(rightSideUp) { colorString = new String[]{"Front", "Back"}; @@ -274,7 +271,7 @@ protected void drawBackground(Svg g, HashMap colorScheme) { } } - protected void drawClock(Svg g, int clock, int position, HashMap colorScheme) { + protected void drawClock(Svg g, int clock, int position, Map colorScheme) { Transform t = new Transform(); t.rotate(Math.toRadians(position*30)); int netX = 0; @@ -329,7 +326,7 @@ protected void drawClock(Svg g, int clock, int position, HashMap g.appendChild(handBase); } - protected void drawPins(Svg g, boolean[] pins, HashMap colorScheme) { + protected void drawPins(Svg g, boolean[] pins, Map colorScheme) { Transform t = new Transform(); t.translate(radius + gap, radius + gap); int k = 0; @@ -353,7 +350,7 @@ protected void drawPins(Svg g, boolean[] pins, HashMap colorSchem } } - protected void drawPin(Svg g, Transform t, boolean pinUp, HashMap colorScheme) { + protected void drawPin(Svg g, Transform t, boolean pinUp, Map colorScheme) { Circle pin = new Circle(0, 0, pinRadius); pin.setTransform(t); pin.setStroke(Color.BLACK); diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/CubePuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/CubePuzzle.java index e0fa20fb..edfa64fd 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/CubePuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/CubePuzzle.java @@ -14,7 +14,7 @@ @Export public class CubePuzzle extends Puzzle { - public static enum Face { + public enum Face { R, U, F, L, D, B; public Face oppositeFace() { @@ -23,7 +23,7 @@ public Face oppositeFace() { } private static final String[] DIR_TO_STR = new String[] { null, "", "2", "'" }; - private static HashMap faceRotationsByName = new HashMap(); + private static final Map faceRotationsByName = new HashMap<>(); static { faceRotationsByName.put(Face.R, "x"); faceRotationsByName.put(Face.U, "y"); @@ -96,7 +96,7 @@ protected CubeMove[][] getRandomOrientationMoves(int thickness) { int i = 0; for(CubeMove randomUFaceMove : randomUFaceMoves) { for(CubeMove randomFFaceMove : randomFFaceMoves) { - ArrayList moves = new ArrayList(); + List moves = new ArrayList<>(); if(randomUFaceMove != null) { moves.add(randomUFaceMove); } @@ -219,7 +219,7 @@ private static void slice(Face face, int slice, int dir, int[][][] image) { } } - private static HashMap defaultColorScheme = new HashMap(); + private static final Map defaultColorScheme = new HashMap<>(); static { defaultColorScheme.put("B", Color.BLUE); defaultColorScheme.put("D", Color.YELLOW); @@ -229,8 +229,8 @@ private static void slice(Face face, int slice, int dir, int[][][] image) { defaultColorScheme.put("U", Color.WHITE); } @Override - public HashMap getDefaultColorScheme() { - return new HashMap(defaultColorScheme); + public Map getDefaultColorScheme() { + return new HashMap<>(defaultColorScheme); } @Override @@ -249,7 +249,7 @@ private static Dimension getImageSize(int gap, int unitSize, int size) { return new Dimension(getCubeViewWidth(unitSize, gap, size), getCubeViewHeight(unitSize, gap, size)); } - private void drawCube(Svg g, int[][][] state, int gap, int cubieSize, HashMap colorScheme) { + private void drawCube(Svg g, int[][][] state, int gap, int cubieSize, Map colorScheme) { paintCubeFace(g, gap, 2*gap+size*cubieSize, size, cubieSize, state[Face.L.ordinal()], colorScheme); paintCubeFace(g, 2*gap+size*cubieSize, 3*gap+2*size*cubieSize, size, cubieSize, state[Face.D.ordinal()], colorScheme); paintCubeFace(g, 4*gap+3*size*cubieSize, 2*gap+size*cubieSize, size, cubieSize, state[Face.B.ordinal()], colorScheme); @@ -258,7 +258,7 @@ private void drawCube(Svg g, int[][][] state, int gap, int cubieSize, HashMap colorScheme) { + private void paintCubeFace(Svg g, int x, int y, int size, int cubieSize, int[][] faceColors, Map colorScheme) { for(int row = 0; row < size; row++) { for(int col = 0; col < size; col++) { int tempx = x + col*cubieSize; @@ -495,32 +495,32 @@ public TwoByTwoState toTwoByTwoState() { */ public String toFaceCube() { assert size == 3; - String state = ""; + StringBuilder state = new StringBuilder(); for(char f : "URFDLB".toCharArray()) { Face face = Face.valueOf("" + f); int[][] faceArr = image[face.ordinal()]; - for(int i = 0; i < faceArr.length; i++) { - for(int j = 0; j < faceArr[i].length; j++) { - state += Face.values()[faceArr[i][j]].toString(); + for (int[] faceState : faceArr) { + for (int piece : faceState) { + state.append(Face.values()[piece].toString()); } } } - return state; + return state.toString(); } @Override - public LinkedHashMap getSuccessorsByName() { + public Map getSuccessorsByName() { return getSuccessorsWithinSlice(size - 1, true); } @Override - public HashMap getScrambleSuccessors() { - return getSuccessorsWithinSlice((int) (size / 2) - 1, false); + public Map getScrambleSuccessors() { + return getSuccessorsWithinSlice((size / 2) - 1, false); } @Override - public HashMap getCanonicalMovesByState() { - HashMap reversed = new HashMap(); + public Map getCanonicalMovesByState() { + Map reversed = new HashMap<>(); for (Map.Entry entry : getScrambleSuccessors().entrySet()) { reversed.put(entry.getValue(), entry.getKey()); @@ -529,8 +529,8 @@ public HashMap getCanonicalMovesByState() { return reversed; } - private LinkedHashMap getSuccessorsWithinSlice(int maxSlice, boolean includeRedundant) { - LinkedHashMap successors = new LinkedHashMap(); + private Map getSuccessorsWithinSlice(int maxSlice, boolean includeRedundant) { + Map successors = new LinkedHashMap<>(); for(int innerSlice = 0; innerSlice <= maxSlice; innerSlice++) { for(Face face : Face.values()) { boolean halfOfEvenCube = size % 2 == 0 && (innerSlice == (size / 2) - 1); @@ -569,7 +569,7 @@ public int hashCode() { return Arrays.deepHashCode(image); } - protected Svg drawScramble(HashMap colorScheme) { + protected Svg drawScramble(Map colorScheme) { Svg svg = new Svg(getPreferredSize()); drawCube(svg, image, gap, cubieSize, colorScheme); return svg; diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/FourByFourCubePuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/FourByFourCubePuzzle.java index 49ed8d31..8c47380d 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/FourByFourCubePuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/FourByFourCubePuzzle.java @@ -2,6 +2,8 @@ import java.util.Random; +import cs.threephase.Edge3; +import cs.threephase.Search; import org.worldcubeassociation.tnoodle.scrambles.AlgorithmBuilder; import org.worldcubeassociation.tnoodle.scrambles.AlgorithmBuilder.MergingMode; import org.worldcubeassociation.tnoodle.scrambles.InvalidMoveException; @@ -11,19 +13,15 @@ @Export public class FourByFourCubePuzzle extends CubePuzzle { - private ThreadLocal threePhaseSearcher = null; + private final ThreadLocal threePhaseSearcher; public FourByFourCubePuzzle() { super(4); - threePhaseSearcher = new ThreadLocal() { - protected cs.threephase.Search initialValue() { - return new cs.threephase.Search(); - }; - }; + threePhaseSearcher = ThreadLocal.withInitial(Search::new); } public double getInitializationStatus() { - return cs.threephase.Edge3.initStatus(); + return Edge3.initStatus(); } @Override diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/MegaminxPuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/MegaminxPuzzle.java index 83a835ee..7e568db0 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/MegaminxPuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/MegaminxPuzzle.java @@ -7,10 +7,8 @@ import org.worldcubeassociation.tnoodle.svglite.Path; import org.worldcubeassociation.tnoodle.svglite.Point2D; import org.worldcubeassociation.tnoodle.svglite.Text; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Random; + +import java.util.*; import org.worldcubeassociation.tnoodle.scrambles.InvalidScrambleException; import org.worldcubeassociation.tnoodle.scrambles.Puzzle; @@ -20,7 +18,7 @@ @Export public class MegaminxPuzzle extends Puzzle { - private static enum Face { + private enum Face { U, BL, BR, R, F, L, D, DR, DBR, B, DBL, DL; // TODO We could rename faces so we can just do +6 mod 12 here instead. @@ -192,22 +190,24 @@ private static void swapWholeFace(int[][] image, int f1, int s1, int f2, int s2, swapCenters(image, f1, f2, f3, f4, f5); } + private static final Map defaultColorScheme = new HashMap<>(); + static { + defaultColorScheme.put("U", new Color(0xffffff)); + defaultColorScheme.put("BL", new Color(0xffcc00)); + defaultColorScheme.put("BR", new Color(0x0000b3)); + defaultColorScheme.put("R", new Color(0xdd0000)); + defaultColorScheme.put("F", new Color(0x006600)); + defaultColorScheme.put("L", new Color(0x8a1aff)); + defaultColorScheme.put("D", new Color(0x999999)); + defaultColorScheme.put("DR", new Color(0xffffb3)); + defaultColorScheme.put("DBR", new Color(0xff99ff)); + defaultColorScheme.put("B", new Color(0x71e600)); + defaultColorScheme.put("DBL", new Color(0xff8433)); + defaultColorScheme.put("DL", new Color(0x88ddff)); + } @Override - public HashMap getDefaultColorScheme() { - HashMap colors = new HashMap(); - colors.put("U", new Color(0xffffff)); - colors.put("BL", new Color(0xffcc00)); - colors.put("BR", new Color(0x0000b3)); - colors.put("R", new Color(0xdd0000)); - colors.put("F", new Color(0x006600)); - colors.put("L", new Color(0x8a1aff)); - colors.put("D", new Color(0x999999)); - colors.put("DR", new Color(0xffffb3)); - colors.put("DBR", new Color(0xff99ff)); - colors.put("B", new Color(0x71e600)); - colors.put("DBL", new Color(0xff8433)); - colors.put("DL", new Color(0x88ddff)); - return colors; + public Map getDefaultColorScheme() { + return new HashMap<>(defaultColorScheme); } private static Dimension getImageSize(int gap, int minxRad, String variation) { @@ -280,8 +280,8 @@ private static Path getPentagon(double x, double y, boolean up, int minxRad) { double magicShiftNumber = d*0.6+minxRad*(f+gg); double shift = leftCenterX+magicShiftNumber; - public HashMap getFaceBoundaries() { - HashMap faces = new HashMap(); + public Map getFaceBoundaries() { + HashMap faces = new HashMap<>(); faces.put(Face.U, getPentagon(leftCenterX , leftCenterY , true , minxRad)); faces.put(Face.BL, getPentagon(leftCenterX-c, leftCenterY-e, false, minxRad)); faces.put(Face.BR, getPentagon(leftCenterX+c, leftCenterY-e, false, minxRad)); @@ -324,7 +324,7 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { } char side = (j % 2 == 0) ? 'R' : 'D'; dir = r.nextInt(2); - scramble.append(side + ((dir == 0) ? "++" : "--")); + scramble.append(side).append((dir == 0) ? "++" : "--"); } scramble.append(" U"); if(dir != 0) { @@ -343,7 +343,7 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { return new PuzzleStateAndGenerator(state, scrambleStr); } - private int centerIndex = 10; + private final int centerIndex = 10; private boolean isNormalized(int[][] image) { return image[Face.U.ordinal()][centerIndex] == Face.U.ordinal() && image[Face.F.ordinal()][centerIndex] == Face.F.ordinal(); } @@ -452,7 +452,7 @@ public MegaminxState(int[][] image) { public PuzzleState getNormalized() { if(normalizedState == null) { int[][] normalizedImage = normalize(image); - normalizedState = new MegaminxState(normalize(image)); + normalizedState = new MegaminxState(normalizedImage); } return normalizedState; } @@ -462,8 +462,8 @@ public boolean isNormalized() { } @Override - public LinkedHashMap getSuccessorsByName() { - LinkedHashMap successors = new LinkedHashMap(); + public Map getSuccessorsByName() { + Map successors = new LinkedHashMap<>(); String[] prettyDir = new String[] { null, "", "2", "2'", "'" }; for(Face face : Face.values()) { @@ -478,7 +478,7 @@ public LinkedHashMap getSuccessorsByName() { } } - HashMap pochmannFaceNames = new HashMap(); + Map pochmannFaceNames = new HashMap<>(); pochmannFaceNames.put("R", Face.DBR); pochmannFaceNames.put("D", Face.D); String[] prettyPochmannDir = new String[] { null, "+", "++", "--" , "-"}; @@ -496,9 +496,9 @@ public LinkedHashMap getSuccessorsByName() { } @Override - public HashMap getScrambleSuccessors() { - HashMap successors = getSuccessorsByName(); - HashMap scrambleSuccessors = new HashMap(); + public Map getScrambleSuccessors() { + Map successors = getSuccessorsByName(); + Map scrambleSuccessors = new HashMap<>(); for(String turn : new String[] { "R++", "R--", "D++", "D--", "U", "U2", "U2'", "U'" }) { scrambleSuccessors.put(turn, successors.get(turn)); } @@ -517,14 +517,14 @@ public int hashCode() { } @Override - protected Svg drawScramble(HashMap colorScheme) { + protected Svg drawScramble(Map colorScheme) { Svg svg = new Svg(getPreferredSize()); drawMinx(svg, gap, minxRad, colorScheme); return svg; } - private void drawMinx(Svg g, int gap, int minxRad, HashMap colorScheme) { - HashMap pentagons = getFaceBoundaries(); + private void drawMinx(Svg g, int gap, int minxRad, Map colorScheme) { + Map pentagons = getFaceBoundaries(); for(Face face : pentagons.keySet()) { int f = face.ordinal(); int rotateCounterClockwise; @@ -546,7 +546,7 @@ private void drawMinx(Svg g, int gap, int minxRad, HashMap colorS } } - private void drawPentagon(Svg g, Path p, int[] state, int rotateCounterClockwise, String label, HashMap colorScheme) { + private void drawPentagon(Svg g, Path p, int[] state, int rotateCounterClockwise, String label, Map colorScheme) { double[] xpoints = new double[5]; double[] ypoints = new double[5]; PathIterator iter = p.getPathIterator(); diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/PyraminxPuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/PyraminxPuzzle.java index eb02ee3f..3e806fed 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/PyraminxPuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/PyraminxPuzzle.java @@ -6,10 +6,8 @@ import org.worldcubeassociation.tnoodle.svglite.Path; import org.worldcubeassociation.tnoodle.svglite.PathIterator; import org.worldcubeassociation.tnoodle.svglite.Point2D; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Random; + +import java.util.*; import java.util.logging.Logger; import org.worldcubeassociation.tnoodle.puzzle.PyraminxSolver.PyraminxSolverState; @@ -26,7 +24,7 @@ public class PyraminxPuzzle extends Puzzle { private static final int MIN_SCRAMBLE_LENGTH = 11; private static final boolean SCRAMBLE_LENGTH_INCLUDES_TIPS = true; - private PyraminxSolver pyraminxSolver = null; + private final PyraminxSolver pyraminxSolver; public PyraminxPuzzle() { pyraminxSolver = new PyraminxSolver(); @@ -56,7 +54,7 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { private static final int pieceSize = 30; private static final int gap = 5; - private static final HashMap defaultColorScheme = new HashMap(); + private static final Map defaultColorScheme = new HashMap<>(); static { defaultColorScheme.put("F", new Color(0x00FF00)); defaultColorScheme.put("D", new Color(0xFFFF00)); @@ -64,8 +62,8 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { defaultColorScheme.put("R", new Color(0x0000FF)); } @Override - public HashMap getDefaultColorScheme() { - return new HashMap(defaultColorScheme); + public Map getDefaultColorScheme() { + return new HashMap<>(defaultColorScheme); } @Override @@ -442,8 +440,8 @@ public String solveIn(int n) { } @Override - public LinkedHashMap getSuccessorsByName() { - LinkedHashMap successors = new LinkedHashMap(); + public Map getSuccessorsByName() { + Map successors = new LinkedHashMap<>(); String axes = "ulrb"; for(int axis = 0; axis < axes.length(); axis++) { @@ -485,7 +483,7 @@ public int hashCode() { } @Override - protected Svg drawScramble(HashMap colorScheme) { + protected Svg drawScramble(Map colorScheme) { Dimension preferredSize = getPreferredSize(); Svg svg = new Svg(preferredSize); svg.setStroke(2, 10, "round"); diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SkewbPuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SkewbPuzzle.java index 693e22af..8a3acbf9 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SkewbPuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SkewbPuzzle.java @@ -5,10 +5,8 @@ import org.worldcubeassociation.tnoodle.svglite.Dimension; import org.worldcubeassociation.tnoodle.svglite.Path; import org.worldcubeassociation.tnoodle.svglite.Transform; -import java.util.Arrays; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Random; + +import java.util.*; import java.util.logging.Logger; import org.worldcubeassociation.tnoodle.puzzle.SkewbSolver.SkewbSolverState; @@ -23,7 +21,7 @@ public class SkewbPuzzle extends Puzzle { private static final int MIN_SCRAMBLE_LENGTH = 11; private static final Logger l = Logger.getLogger(SkewbPuzzle.class.getName()); - private SkewbSolver skewbSolver = null; + private final SkewbSolver skewbSolver; private static final int pieceSize = 30; private static final int gap = 3; @@ -55,7 +53,7 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { */ - private static final HashMap defaultColorScheme = new HashMap(); + private static final Map defaultColorScheme = new HashMap<>(); static { defaultColorScheme.put("U", Color.WHITE); defaultColorScheme.put("R", Color.BLUE); @@ -66,8 +64,8 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { } @Override - public HashMap getDefaultColorScheme() { - return new HashMap(defaultColorScheme); + public Map getDefaultColorScheme() { + return new HashMap<>(defaultColorScheme); } private Transform[] getFaceTrans() { @@ -126,7 +124,7 @@ public class SkewbState extends PuzzleState { * | 3 4 | * +---------+ */ - private int[][] image = new int[6][5]; + private final int[][] image = new int[6][5]; SkewbState() { for (int i=0; i<6; i++) { @@ -138,9 +136,7 @@ public class SkewbState extends PuzzleState { SkewbState(int[][] _image) { for (int i=0; i<6; i++) { - for (int j=0; j<5; j++) { - image[i][j] = _image[i][j]; - } + System.arraycopy(_image[i], 0, image[i], 0, 5); } } @@ -214,7 +210,8 @@ private Path[] getFacePaths() { return p; } - protected Svg drawScramble(HashMap colorScheme) { + @Override + protected Svg drawScramble(Map colorScheme) { Svg g = new Svg(getPreferredSize()); Color[] scheme = new Color[6]; for(int i = 0; i < scheme.length; i++) { @@ -233,8 +230,9 @@ protected Svg drawScramble(HashMap colorScheme) { return g; } - public LinkedHashMap getSuccessorsByName() { - LinkedHashMap successors = new LinkedHashMap(); + @Override + public Map getSuccessorsByName() { + Map successors = new LinkedHashMap<>(); String axes = "RULB"; for(int axis = 0; axis < axes.length(); axis++) { char face = axes.charAt(axis); diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SkewbSolver.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SkewbSolver.java index 73c49985..65a18e99 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SkewbSolver.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SkewbSolver.java @@ -257,7 +257,7 @@ public String generateExactly(SkewbSolverState state, int length, Random randomi * In another word, "F R" is converted to "B U". The correctness can be easily verified and the procedure is recursable. */ private String getSolution(int[] sol, int solutionLength) { - StringBuffer sb = new StringBuffer(); + StringBuilder sb = new StringBuilder(); String[] move2str = { "L", "R", "B", "U" };//RLDB (in jaap's notation) rotated by z2 for (int i = 0; i < solutionLength; i++) { int axis = sol[i] >> 1; @@ -270,11 +270,10 @@ private String getSolution(int[] sol, int solutionLength) { move2str[3] = temp; } } - sb.append(move2str[axis] + ((pow == 1) ? "'" : "")); + sb.append(move2str[axis]).append((pow == 1) ? "'" : ""); sb.append(" "); } - String scrambleSequence = sb.toString().trim(); - return scrambleSequence; + return sb.toString().trim(); } } diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SquareOnePuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SquareOnePuzzle.java index 354d82ba..02c8291b 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SquareOnePuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/SquareOnePuzzle.java @@ -19,16 +19,12 @@ public class SquareOnePuzzle extends Puzzle { private static final int radius = 32; - private ThreadLocal twoPhaseSearcher; + private final ThreadLocal twoPhaseSearcher; public SquareOnePuzzle() { wcaMinScrambleDistance = 11; - twoPhaseSearcher = new ThreadLocal() { - protected Search initialValue() { - return new Search(); - }; - }; + twoPhaseSearcher = ThreadLocal.withInitial(Search::new); } @Override @@ -45,7 +41,7 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { return new PuzzleStateAndGenerator(state, scramble); } - private static HashMap defaultColorScheme = new HashMap(); + private static final Map defaultColorScheme = new HashMap<>(); static { defaultColorScheme.put("B", new Color(255, 128, 0)); //orange heraldic tincture defaultColorScheme.put("D", Color.WHITE); @@ -55,8 +51,8 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { defaultColorScheme.put("U", Color.YELLOW); } @Override - public HashMap getDefaultColorScheme() { - return new HashMap(defaultColorScheme); + public Map getDefaultColorScheme() { + return new HashMap<>(defaultColorScheme); } @Override @@ -197,8 +193,8 @@ protected int getRandomMoveCount() { return 40; } - static HashMap wcaCostsByMove = new HashMap(); - static HashMap slashabilityCostsByMove = new HashMap(); + static Map wcaCostsByMove = new HashMap<>(); + static Map slashabilityCostsByMove = new HashMap<>(); static { for(int top = -5; top <= 6; top++) { for(int bottom = -5; bottom <= 6; bottom++) { @@ -282,18 +278,14 @@ private int[] doRotateTopAndBottom(int top, int bottom) { top = ((-top % 12) + 12) % 12; int[] newPieces = cloneArr(pieces); int[] t = new int[12]; - for(int i = 0; i < 12; i++) { - t[i] = newPieces[i]; - } + System.arraycopy(newPieces, 0, t, 0, 12); for(int i = 0; i < 12; i++) { newPieces[i] = t[(top + i) % 12]; } bottom = ((-bottom % 12) + 12) % 12; - for(int i = 0; i < 12; i++) { - t[i] = newPieces[i+12]; - } + System.arraycopy(newPieces, 12, t, 0, 12); for(int i = 0; i < 12; i++) { newPieces[i+12] = t[(bottom + i) % 12]; } @@ -312,8 +304,8 @@ public int getMoveCost(String move) { } @Override - public HashMap getScrambleSuccessors() { - HashMap successors = getSuccessorsByName(); + public Map getScrambleSuccessors() { + Map successors = getSuccessorsByName(); Iterator iter = successors.keySet().iterator(); while(iter.hasNext()) { String key = iter.next(); @@ -326,8 +318,8 @@ public HashMap getScrambleSuccessors() { } @Override - public LinkedHashMap getSuccessorsByName() { - LinkedHashMap successors = new LinkedHashMap(); + public Map getSuccessorsByName() { + Map successors = new LinkedHashMap<>(); for(int top = -5; top <= 6; top++) { for(int bottom = -5; bottom <= 6; bottom++) { if(top == 0 && bottom == 0) { @@ -350,7 +342,7 @@ public String solveIn(int n) { // apparently sq12phase can neither represent nor solve "unslashable" squares if (!this.canSlash()) { // getScrambleSuccessors automatically filters for slashability - HashMap slashableSuccessors = this.getScrambleSuccessors(); + Map slashableSuccessors = this.getScrambleSuccessors(); Map.Entry bestSlashable = null; int currentMin = Integer.MAX_VALUE; @@ -408,7 +400,7 @@ private String solveWithSlashabilityIn(int n, String slashabilityMove, SquareOne return null; } - AlgorithmBuilder ab = new AlgorithmBuilder(this.getPuzzle(), AlgorithmBuilder.MergingMode.CANONICALIZE_MOVES, preSlashabilityState); + AlgorithmBuilder ab = new AlgorithmBuilder(AlgorithmBuilder.MergingMode.CANONICALIZE_MOVES, preSlashabilityState); // initially just hope that slashability cancels with the n-move optimal solution ab.appendMove(slashabilityMove); @@ -435,7 +427,7 @@ public int hashCode() { } @Override - protected Svg drawScramble(HashMap colorSchemeMap) { + protected Svg drawScramble(Map colorSchemeMap) { Svg g = new Svg(getPreferredSize()); g.setStroke(2, 10, "round"); diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/ThreeByThreeCubePuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/ThreeByThreeCubePuzzle.java index f893d39d..6f77692f 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/ThreeByThreeCubePuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/ThreeByThreeCubePuzzle.java @@ -19,18 +19,14 @@ public class ThreeByThreeCubePuzzle extends CubePuzzle { private static final int THREE_BY_THREE_TIMEMIN = 200; //milliseconds private static final int THREE_BY_THREE_TIMEOUT = 60*1000; //milliseconds - private ThreadLocal twoPhaseSearcher = null; + private final ThreadLocal twoPhaseSearcher; public ThreeByThreeCubePuzzle() { super(3); String newMinDistance = System.getenv("TNOODLE_333_MIN_DISTANCE"); if(newMinDistance != null) { wcaMinScrambleDistance = Integer.parseInt(newMinDistance); } - twoPhaseSearcher = new ThreadLocal() { - protected SearchWCA initialValue() { - return new SearchWCA(); - }; - }; + twoPhaseSearcher = ThreadLocal.withInitial(SearchWCA::new); } @Override @@ -40,7 +36,7 @@ protected String solveIn(PuzzleState ps, int n) { public String solveIn(PuzzleState ps, int n, String firstAxisRestriction, String lastAxisRestriction) { CubeState cs = (CubeState) ps; - if(this.equals(getSolvedState())) { + if(cs.equals(getSolvedState())) { // TODO - apparently min2phase can't solve the solved cube return ""; } diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/TwoByTwoCubePuzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/TwoByTwoCubePuzzle.java index 91db07c5..25270161 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/TwoByTwoCubePuzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/TwoByTwoCubePuzzle.java @@ -14,7 +14,7 @@ public class TwoByTwoCubePuzzle extends CubePuzzle { private static final int TWO_BY_TWO_MIN_SCRAMBLE_LENGTH = 11; - private TwoByTwoSolver twoSolver = null; + private final TwoByTwoSolver twoSolver; public TwoByTwoCubePuzzle() { super(2); wcaMinScrambleDistance = 4; @@ -38,7 +38,6 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { protected String solveIn(PuzzleState ps, int n) { CubeState cs = (CubeState) ps; - String solution = twoSolver.solveIn(cs.toTwoByTwoState(), n); - return solution; + return twoSolver.solveIn(cs.toTwoByTwoState(), n); } } diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/TwoByTwoSolver.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/TwoByTwoSolver.java index c669f359..f42cc7ac 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/TwoByTwoSolver.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/puzzle/TwoByTwoSolver.java @@ -199,8 +199,8 @@ private static void initMoves(){ /** * Fill the pruning tables for the permutation and orientation coordinates. */ - private static int[] prunPerm = new int[N_PERM]; - private static int[] prunOrient = new int[N_ORIENT]; + private static final int[] prunPerm = new int[N_PERM]; + private static final int[] prunOrient = new int[N_ORIENT]; private static void initPrun(){ for (int perm=0; perm moves = new ArrayList(); + private final List moves = new ArrayList<>(); /** * states.get(i) = state achieved by applying moves[0]...moves[i-1] */ - private ArrayList states = new ArrayList(); + private final List states = new ArrayList<>(); /** * If we are in CANONICALIZE_MOVES MergingMode, then something like * Uw Dw on a 4x4x4 will become Uw2. This means the state we end @@ -24,14 +25,13 @@ public class AlgorithmBuilder { */ private PuzzleState originalState, unNormalizedState; private int totalCost; - private MergingMode mergingMode = MergingMode.NO_MERGING; - private Puzzle puzzle; + private final MergingMode mergingMode; + public AlgorithmBuilder(Puzzle puzzle, MergingMode mergingMode) { - this(puzzle, mergingMode, puzzle.getSolvedState()); + this(mergingMode, puzzle.getSolvedState()); } - public AlgorithmBuilder(Puzzle puzzle, MergingMode mergingMode, PuzzleState originalState) { - this.puzzle = puzzle; + public AlgorithmBuilder(MergingMode mergingMode, PuzzleState originalState) { this.mergingMode = mergingMode; resetToState(originalState); } @@ -45,7 +45,7 @@ private void resetToState(PuzzleState originalState) { states.add(unNormalizedState); } - public static enum MergingMode { + public enum MergingMode { // There are several degrees of manipulation we can choose to do // while building an algorithm. Here they are, ranging from least to // most aggressive. Examples are on a 3x3x3. @@ -116,7 +116,7 @@ public IndexAndMove findBestIndexForMove(String move, MergingMode mergingMode) t } PuzzleState newNormalizedState = newUnNormalizedState.getNormalized(); - HashMap successors = getState().getCanonicalMovesByState(); + Map successors = getState().getCanonicalMovesByState(); move = null; // Search for the right move to do to our current state in // order to match up with newNormalizedState. @@ -202,7 +202,7 @@ public void appendMove(String newMove) throws InvalidMoveException { } public String popMove(int index) { - ArrayList movesCopy = new ArrayList(moves); + List movesCopy = new ArrayList<>(moves); String poppedMove = movesCopy.remove(index); resetToState(originalState); diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/InvalidMoveException.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/InvalidMoveException.java index 3621a2b5..c5ef7090 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/InvalidMoveException.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/InvalidMoveException.java @@ -1,6 +1,5 @@ package org.worldcubeassociation.tnoodle.scrambles; -@SuppressWarnings("serial") public class InvalidMoveException extends Exception { public InvalidMoveException(String move) { super("Invalid move: " + move); diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/InvalidScrambleException.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/InvalidScrambleException.java index 8b74000f..aa39d72f 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/InvalidScrambleException.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/InvalidScrambleException.java @@ -1,6 +1,5 @@ package org.worldcubeassociation.tnoodle.scrambles; -@SuppressWarnings("serial") public class InvalidScrambleException extends Exception { public InvalidScrambleException(String scramble) { super(scramble, null); diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/LazySupplier.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/LazySupplier.java index 3d4f4627..fcddb833 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/LazySupplier.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/LazySupplier.java @@ -1,7 +1,6 @@ package org.worldcubeassociation.tnoodle.scrambles; import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; class LazySupplier { private T instance; @@ -27,13 +26,7 @@ private T provideInstance() { Class[] classes = this.getCtorArgClasses(); Constructor constructor = this.supplyingClass.getConstructor(classes); return constructor.newInstance(this.ctorArgs); - } catch (InstantiationException e) { - e.printStackTrace(); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (InvocationTargetException e) { - e.printStackTrace(); - } catch (NoSuchMethodException e) { + } catch (ReflectiveOperationException e) { e.printStackTrace(); } diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/Puzzle.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/Puzzle.java index 12ad4be8..05dd9332 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/Puzzle.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/Puzzle.java @@ -98,7 +98,7 @@ public final String generateWcaScramble(Random r) { /** * @return A *new* HashMap mapping face names to Colors. */ - public abstract HashMap getDefaultColorScheme(); + public abstract Map getDefaultColorScheme(); private String[] generateScrambles(Random r, int count) { String[] scrambles = new String[count]; @@ -147,7 +147,7 @@ public final String[] generateSeededScrambles(String seed, int count) { return generateSeededScrambles(seed.getBytes(), count); } - private final String generateSeededScramble(byte[] seed) { + private String generateSeededScramble(byte[] seed) { // We must create our own Random because // other threads can access the static one. // Also, setSeed supplements an existing seed, @@ -159,7 +159,7 @@ private final String generateSeededScramble(byte[] seed) { r.setSeed(seed); return generateWcaScramble(r); } - private final String[] generateSeededScrambles(byte[] seed, int count) { + private String[] generateSeededScrambles(byte[] seed, int count) { // We must create our own Random because // other threads can access the static one. // Also, setSeed supplements an existing seed, @@ -183,9 +183,9 @@ public String toString() { */ @Export public String[] getFaceNames() { - ArrayList faces = new ArrayList(getDefaultColorScheme().keySet()); - Collections.sort(faces); - return faces.toArray(new String[faces.size()]); + return getDefaultColorScheme().keySet().stream() + .sorted() + .toArray(String[]::new); } /** @@ -193,8 +193,8 @@ public String[] getFaceNames() { * @param scheme TODO, see above * @return TODO, see above */ - public HashMap parseColorScheme(String scheme) { - HashMap colorScheme = getDefaultColorScheme(); + public Map parseColorScheme(String scheme) { + Map colorScheme = getDefaultColorScheme(); if(scheme != null && !scheme.isEmpty()) { String[] faces = getFaceNames(); String[] colors; @@ -235,11 +235,11 @@ public HashMap parseColorScheme(String scheme) { * @return An SVG object representing the drawn scramble. * @throws InvalidScrambleException If scramble is invalid. */ - public Svg drawScramble(String scramble, HashMap colorScheme) throws InvalidScrambleException { + public Svg drawScramble(String scramble, Map colorScheme) throws InvalidScrambleException { if(scramble == null) { scramble = ""; } - HashMap colorSchemeCopy = colorScheme; + Map colorSchemeCopy = colorScheme; colorScheme = getDefaultColorScheme(); if(colorSchemeCopy != null) { colorScheme.putAll(colorSchemeCopy); @@ -253,7 +253,7 @@ public Svg drawScramble(String scramble, HashMap colorScheme) thr // vertical and horizontal lines. // See http://stackoverflow.com/questions/7589650/drawing-grid-with-jquery-svg-produces-2px-lines-instead-of-1px Group g = new Group(); - ArrayList children = svg.getChildren(); + List children = svg.getChildren(); while(!children.isEmpty()) { g.appendChild(children.remove(0)); } @@ -287,11 +287,11 @@ public Dimension getPreferredSize(int maxWidth, int maxHeight) { } public static class Bucket implements Comparable> { - private LinkedList contents; - private int value; + private final LinkedList contents; + private final int value; public Bucket(int value) { this.value = value; - this.contents = new LinkedList(); + this.contents = new LinkedList<>(); } public int getValue() { @@ -311,7 +311,7 @@ public boolean isEmpty() { } public String toString() { - return "#: " + value + ": " + contents.toString(); + return "#: " + value + ": " + contents; } @Override @@ -330,14 +330,14 @@ public boolean equals(Object o) { } public static class SortedBuckets { - TreeSet> buckets; + private final TreeSet> buckets; public SortedBuckets() { - buckets = new TreeSet>(); + buckets = new TreeSet<>(); } public void add(H element, int value) { Bucket bucket; - Bucket searchBucket = new Bucket(value); + Bucket searchBucket = new Bucket<>(value); if(!buckets.contains(searchBucket)) { // There is no bucket yet for value, so we create one. bucket = searchBucket; @@ -385,10 +385,10 @@ protected String solveIn(PuzzleState ps, int n) { return ""; } - HashMap seenSolved = new HashMap(); - SortedBuckets fringeSolved = new SortedBuckets(); - HashMap seenScrambled = new HashMap(); - SortedBuckets fringeScrambled = new SortedBuckets(); + Map seenSolved = new HashMap<>(); + SortedBuckets fringeSolved = new SortedBuckets<>(); + Map seenScrambled = new HashMap<>(); + SortedBuckets fringeScrambled = new SortedBuckets<>(); // We're only interested in solutions of cost <= n int bestIntersectionCost = n + 1; @@ -431,9 +431,9 @@ protected String solveIn(PuzzleState ps, int n) { } // We are using references for a more concise code. - HashMap seenExtending; + Map seenExtending; SortedBuckets fringeExtending; - HashMap seenComparing; + Map seenComparing; SortedBuckets fringeComparing; int minExtendingFringe, minComparingFringe; if(extendSolved) { @@ -480,7 +480,7 @@ protected String solveIn(PuzzleState ps, int n) { } - HashMap movesByState = node.getCanonicalMovesByState(); + Map movesByState = node.getCanonicalMovesByState(); for(PuzzleState next : movesByState.keySet()) { int moveCost = node.getMoveCost(movesByState.get(next)); int nextDistance = distance + moveCost; @@ -542,7 +542,7 @@ protected String solveIn(PuzzleState ps, int n) { // Step 2: bestIntersection <----- scrambled - AlgorithmBuilder solution = new AlgorithmBuilder(this, MergingMode.CANONICALIZE_MOVES, ps); + AlgorithmBuilder solution = new AlgorithmBuilder(MergingMode.CANONICALIZE_MOVES, ps); state = ps; distanceFromScrambled = 0; @@ -621,12 +621,12 @@ public PuzzleState applyAlgorithm(String algorithm) throws InvalidScrambleExcept * @return A mapping of canonical PuzzleState's to the name of * the move that gets you to them. */ - public HashMap getCanonicalMovesByState() { - LinkedHashMap successorsByName = + public Map getCanonicalMovesByState() { + Map successorsByName = getSuccessorsByName(); - HashMap uniqueSuccessors = - new HashMap(); - HashSet statesSeenNormalized = new HashSet(); + Map uniqueSuccessors = + new HashMap<>(); + Set statesSeenNormalized = new HashSet<>(); // We're not interested in any successor states are just a // rotation away. statesSeenNormalized.add(this.getNormalized()); @@ -696,7 +696,7 @@ public int getMoveCost(String move) { * Preferred notations should appear earlier in the * LinkedHashMap. */ - public abstract LinkedHashMap getSuccessorsByName(); + public abstract Map getSuccessorsByName(); /** * By default, this method returns getSuccessorsByName(). Some @@ -728,8 +728,8 @@ public int getMoveCost(String move) { * @return A HashMap mapping move Strings to resulting PuzzleStates. * The move Strings may not contain spaces. */ - public HashMap getScrambleSuccessors() { - HashMap reversed = new HashMap(); + public Map getScrambleSuccessors() { + Map reversed = new HashMap<>(); for (Map.Entry entry : getCanonicalMovesByState().entrySet()) { reversed.put(entry.getValue(), entry.getKey()); @@ -760,7 +760,7 @@ public boolean equalsNormalized(PuzzleState other) { * @param colorScheme The color scheme to use while drawing * @return An Svg instance representing this scramble. */ - protected abstract Svg drawScramble(HashMap colorScheme); + protected abstract Svg drawScramble(Map colorScheme); public Puzzle getPuzzle() { return Puzzle.this; @@ -778,7 +778,7 @@ public boolean isSolved() { * @throws InvalidMoveException if the move is unrecognized. */ public PuzzleState apply(String move) throws InvalidMoveException { - HashMap successors = getSuccessorsByName(); + Map successors = getSuccessorsByName(); if(!successors.containsKey(move)) { throw new InvalidMoveException("Unrecognized turn " + move); } @@ -840,7 +840,7 @@ public PuzzleStateAndGenerator generateRandomMoves(Random r) { AlgorithmBuilder ab = new AlgorithmBuilder( this, MergingMode.NO_MERGING); while(ab.getTotalCost() < getRandomMoveCount()) { - HashMap successors = + Map successors = ab.getState().getScrambleSuccessors(); String move; try { diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/PuzzleImageInfo.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/PuzzleImageInfo.java index 40d3b4b6..f2e6b75e 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/PuzzleImageInfo.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/PuzzleImageInfo.java @@ -3,9 +3,10 @@ import org.worldcubeassociation.tnoodle.svglite.Color; import org.worldcubeassociation.tnoodle.svglite.Dimension; import java.util.HashMap; +import java.util.Map; public class PuzzleImageInfo { - public HashMap colorScheme; + public Map colorScheme; public Dimension size; public PuzzleImageInfo() {} @@ -14,14 +15,14 @@ public PuzzleImageInfo(Puzzle p) { size = p.getPreferredSize(); } - public HashMap toJsonable() { - HashMap jsonable = new HashMap(); - HashMap dim = new HashMap(); + public Map toJsonable() { + Map jsonable = new HashMap<>(); + Map dim = new HashMap<>(); dim.put("width", size.width); dim.put("height", size.height); jsonable.put("size", dim); - HashMap jsonColorScheme = new HashMap(); + Map jsonColorScheme = new HashMap<>(); for(String key : this.colorScheme.keySet()) { jsonColorScheme.put(key, this.colorScheme.get(key).toHex()); } diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/PuzzleRegistry.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/PuzzleRegistry.java index 9f91990a..8c2bdb08 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/PuzzleRegistry.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/PuzzleRegistry.java @@ -20,10 +20,10 @@ public enum PuzzleRegistry { CLOCK(ClockPuzzle.class), SKEWB(SkewbPuzzle.class); - private LazySupplier puzzleSupplier; + private final LazySupplier puzzleSupplier; PuzzleRegistry(Class suppliyingClass, Object... ctorArgs) { - this.puzzleSupplier = new LazySupplier(suppliyingClass, ctorArgs); + this.puzzleSupplier = new LazySupplier<>(suppliyingClass, ctorArgs); } public Puzzle getScrambler() { diff --git a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/ScrambleCacher.java b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/ScrambleCacher.java index 13469e74..e2e4c239 100644 --- a/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/ScrambleCacher.java +++ b/scrambles/src/main/java/org/worldcubeassociation/tnoodle/scrambles/ScrambleCacher.java @@ -2,6 +2,7 @@ import java.security.SecureRandom; import java.util.LinkedList; +import java.util.List; import java.util.Random; import java.util.logging.Level; import java.util.logging.Logger; @@ -19,7 +20,7 @@ public class ScrambleCacher { */ private static final Random r = new SecureRandom(); - private String[] scrambles; + private final String[] scrambles; private volatile int startBuf = 0; private volatile int available = 0; @@ -36,55 +37,51 @@ public ScrambleCacher(final Puzzle puzzle, int cacheSize, final boolean drawScra public ScrambleCacher(final Puzzle puzzle, int cacheSize, final boolean drawScramble) { assert cacheSize > 0; scrambles = new String[cacheSize]; - Thread t = new Thread() { - public void run() { - synchronized(puzzle.getClass()) { - // This thread starts running while scrambler - // is still initializing, we must wait until - // it has finished before we attempt to generate - // any scrambles. + Thread t = new Thread(() -> { + synchronized(puzzle.getClass()) { + // This thread starts running while scrambler + // is still initializing, we must wait until + // it has finished before we attempt to generate + // any scrambles. + } + for(;;) { + String scramble = puzzle.generateWcaScramble(r); + + if(drawScramble) { + // The drawScramble option exists so we can test out generating and drawing + // a bunch of scrambles in 2 threads at the same time. See ScrambleTest. + try { + puzzle.drawScramble(scramble, null); + } catch (InvalidScrambleException e1) { + l.log(Level.SEVERE, + "Error drawing scramble we just created. ", + e1); + } } - for(;;) { - String scramble = puzzle.generateWcaScramble(r); - if(drawScramble) { - // The drawScramble option exists so we can test out generating and drawing - // a bunch of scrambles in 2 threads at the same time. See ScrambleTest. + synchronized(scrambles) { + while(running && available == scrambles.length) { try { - puzzle.drawScramble(scramble, null); - } catch (InvalidScrambleException e1) { - l.log(Level.SEVERE, - "Error drawing scramble we just created. ", - e1); - } + scrambles.wait(); + } catch(InterruptedException ignored) {} } - - synchronized(scrambles) { - while(running && available == scrambles.length) { - try { - scrambles.wait(); - } catch(InterruptedException e) {} - } - if(!running) { - return; - } - scrambles[(startBuf + available) % scrambles.length] = scramble; - available++; - scrambles.notifyAll(); + if(!running) { + return; } - fireScrambleCacheUpdated(); + scrambles[(startBuf + available) % scrambles.length] = scramble; + available++; + scrambles.notifyAll(); } + fireScrambleCacheUpdated(); } - }; - t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { - public void uncaughtException(Thread t, Throwable e) { - l.log(Level.SEVERE, "", e); + }); + t.setUncaughtExceptionHandler((t1, e) -> { + l.log(Level.SEVERE, "", e); - // Let everyone waiting for a scramble know that we have crashed - exception = e; - synchronized(scrambles) { - scrambles.notifyAll(); - } + // Let everyone waiting for a scramble know that we have crashed + exception = e; + synchronized(scrambles) { + scrambles.notifyAll(); } }); t.setDaemon(true); @@ -103,7 +100,7 @@ public boolean isRunning() { return running; } - private LinkedList ls = new LinkedList(); + private final List ls = new LinkedList<>(); /** * This method will notify all listeners that the cache size has changed. * NOTE: Do NOT call this method while holding any monitors! @@ -136,7 +133,7 @@ public String newScramble() { while(available == 0) { try { scrambles.wait(); - } catch(InterruptedException e) {} + } catch(InterruptedException ignored) {} if(exception != null) { throw new RuntimeException(exception); diff --git a/scrambles/src/test/java/org/worldcubeassociation/tnoodle/HugeScrambleTest.java b/scrambles/src/test/java/org/worldcubeassociation/tnoodle/HugeScrambleTest.java index 3c7c7005..44c0500d 100644 --- a/scrambles/src/test/java/org/worldcubeassociation/tnoodle/HugeScrambleTest.java +++ b/scrambles/src/test/java/org/worldcubeassociation/tnoodle/HugeScrambleTest.java @@ -4,7 +4,7 @@ import java.io.IOException; import java.lang.annotation.Annotation; -import java.util.HashMap; +import java.util.Map; import java.util.Random; import java.util.logging.Logger; @@ -105,7 +105,7 @@ public void testSolveIn() throws InvalidScrambleException { System.out.print("Scramble ["+(count+1)+"/"+SCRAMBLE_COUNT+"]: "); Puzzle.PuzzleState state = scrambler.getSolvedState(); for(int i = 0; i < SCRAMBLE_LENGTH; i++){ - HashMap successors = state.getSuccessorsByName(); + Map successors = state.getSuccessorsByName(); String move = Puzzle.choose(r, successors.keySet()); System.out.print(" "+move); state = successors.get(move); @@ -153,15 +153,12 @@ public void testThreads() throws InvalidScrambleException { System.out.println("Generating & drawing 2 sets of " + SCRAMBLE_COUNT + " scrambles simultaneously." + " This is meant to shake out threading problems in scramblers."); final Object[] o = new Object[0]; - ScrambleCacherListener cacherStopper = new ScrambleCacherListener() { - @Override - public void scrambleCacheUpdated(ScrambleCacher src) { - System.out.println(Thread.currentThread() + " " + src.getAvailableCount() + " / " + src.getCacheSize()); - if(src.getAvailableCount() == src.getCacheSize()) { - src.stop(); - synchronized(o) { - o.notify(); - } + ScrambleCacherListener cacherStopper = src -> { + System.out.println(Thread.currentThread() + " " + src.getAvailableCount() + " / " + src.getCacheSize()); + if(src.getAvailableCount() == src.getCacheSize()) { + src.stop(); + synchronized(o) { + o.notify(); } } }; @@ -321,7 +318,7 @@ public void testTwosConverter() throws InvalidMoveException { @Test public void testTwosSolver() throws InvalidScrambleException { CubePuzzle twos = new CubePuzzle(2); - CubePuzzle.CubeState state = (CubePuzzle.CubeState) twos.getSolvedState(); + CubePuzzle.CubeState state = twos.getSolvedState(); String solution = state.solveIn(0); assertEquals(solution, ""); diff --git a/scrambles/src/test/java/org/worldcubeassociation/tnoodle/puzzle/NoInspectionThreeByThreeTest.java b/scrambles/src/test/java/org/worldcubeassociation/tnoodle/puzzle/NoInspectionThreeByThreeTest.java index fb3ba411..d7263eeb 100644 --- a/scrambles/src/test/java/org/worldcubeassociation/tnoodle/puzzle/NoInspectionThreeByThreeTest.java +++ b/scrambles/src/test/java/org/worldcubeassociation/tnoodle/puzzle/NoInspectionThreeByThreeTest.java @@ -11,7 +11,7 @@ import static org.junit.jupiter.api.Assertions.*; public class NoInspectionThreeByThreeTest { - protected static final Map OPPOSITE_FACES = new HashMap(); + protected static final Map OPPOSITE_FACES = new HashMap<>(); @BeforeAll public static void loadOppositeMoves() { @@ -29,7 +29,7 @@ public void testSomething() throws InvalidMoveException, InvalidScrambleExceptio Puzzle twos = new TwoByTwoCubePuzzle(); Collection canonicalMoves = twos.getSolvedState().getCanonicalMovesByState().values(); - List desiredCanonicalMoves = new ArrayList(); + List desiredCanonicalMoves = new ArrayList<>(); List modifiers = Arrays.asList("", "'", "2"); for (char face : "RUF".toCharArray()) { @@ -38,7 +38,7 @@ public void testSomething() throws InvalidMoveException, InvalidScrambleExceptio } } - assertEquals(new HashSet(canonicalMoves), new HashSet(desiredCanonicalMoves)); + assertEquals(new HashSet<>(canonicalMoves), new HashSet<>(desiredCanonicalMoves)); NoInspectionThreeByThreeCubePuzzle threes = new NoInspectionThreeByThreeCubePuzzle(); Puzzle.PuzzleState solved = threes.getSolvedState(); diff --git a/scrambles/src/test/java/org/worldcubeassociation/tnoodle/puzzle/ThreeByThreeCubeFewestMovesTest.java b/scrambles/src/test/java/org/worldcubeassociation/tnoodle/puzzle/ThreeByThreeCubeFewestMovesTest.java index be8fa434..773c03c0 100644 --- a/scrambles/src/test/java/org/worldcubeassociation/tnoodle/puzzle/ThreeByThreeCubeFewestMovesTest.java +++ b/scrambles/src/test/java/org/worldcubeassociation/tnoodle/puzzle/ThreeByThreeCubeFewestMovesTest.java @@ -13,7 +13,7 @@ import static org.junit.jupiter.api.Assertions.*; public class ThreeByThreeCubeFewestMovesTest { - protected static final Map OPPOSITE_FACES = new HashMap(); + protected static final Map OPPOSITE_FACES = new HashMap<>(); @BeforeAll public static void loadOppositeMoves() { @@ -32,7 +32,7 @@ public void testSomething() throws InvalidScrambleException, InvalidMoveExceptio Collection canonicalMoves = threeFm.getSolvedState().getCanonicalMovesByState().values(); - List desiredCanonicalMoves = new ArrayList(); + List desiredCanonicalMoves = new ArrayList<>(); List modifiers = Arrays.asList("", "'", "2"); for (char face : "RUFLDB".toCharArray()) { @@ -41,7 +41,7 @@ public void testSomething() throws InvalidScrambleException, InvalidMoveExceptio } } - Assertions.assertEquals(new HashSet(canonicalMoves), new HashSet(desiredCanonicalMoves)); + Assertions.assertEquals(new HashSet<>(canonicalMoves), new HashSet<>(desiredCanonicalMoves)); Puzzle.PuzzleState solved = threeFm.getSolvedState(); diff --git a/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/Element.java b/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/Element.java index 5431d1e6..bdfd0073 100644 --- a/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/Element.java +++ b/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/Element.java @@ -2,32 +2,34 @@ import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.util.Map; public class Element { protected String tag; - protected HashMap attributes; - protected HashMap style; - protected ArrayList children; + protected Map attributes; + protected Map style; + protected List children; protected String content; public Element(String tag) { this.tag = tag; - this.children = new ArrayList(); - this.attributes = new HashMap(); - this.style = new HashMap(); + this.children = new ArrayList<>(); + this.attributes = new HashMap<>(); + this.style = new HashMap<>(); this.content = null; } public Element(Element e) { this.tag = e.tag; - this.attributes = new HashMap(e.attributes); - this.style = new HashMap(e.style); + this.attributes = new HashMap<>(e.attributes); + this.style = new HashMap<>(e.style); this.children = e.copyChildren(); - this.content = content; + this.content = e.content; } - protected ArrayList copyChildren() { - ArrayList childrenCopy = new ArrayList(); + protected List copyChildren() { + List childrenCopy = new ArrayList<>(); for(Element child : children) { childrenCopy.add(new Element(child)); } @@ -42,7 +44,7 @@ public void setContent(String content) { this.content = content; } - public ArrayList getChildren() { + public List getChildren() { return children; } @@ -50,7 +52,7 @@ public void appendChild(Element child) { children.add(child); } - public HashMap getAttributes() { + public Map getAttributes() { return attributes; } @@ -72,7 +74,7 @@ public String getStyle(String key) { return style.get(key); } - public HashMap getStyle() { + public Map getStyle() { return style; } diff --git a/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/InvalidHexColorException.java b/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/InvalidHexColorException.java index 63e2578f..136aea49 100644 --- a/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/InvalidHexColorException.java +++ b/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/InvalidHexColorException.java @@ -1,6 +1,5 @@ package org.worldcubeassociation.tnoodle.svglite; -@SuppressWarnings("serial") public class InvalidHexColorException extends Exception { public InvalidHexColorException(String invalidHex) { super(invalidHex); diff --git a/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/Path.java b/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/Path.java index 7aa5fd1a..24df4f18 100644 --- a/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/Path.java +++ b/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/Path.java @@ -1,10 +1,11 @@ package org.worldcubeassociation.tnoodle.svglite; import java.util.ArrayList; +import java.util.List; public class Path extends Element { - class Command { + static class Command { int type; double[] coords; public Command(int type, double[] coords) { @@ -22,7 +23,7 @@ public String toString() { } } - protected ArrayList commands = null; + protected List commands = null; public Path() { super("path"); @@ -31,7 +32,7 @@ public Path() { public Path(Path p) { super(p); if(p.commands != null) { - this.commands = new ArrayList(p.commands); + this.commands = new ArrayList<>(p.commands); } } @@ -41,7 +42,7 @@ public PathIterator getPathIterator() { public void moveTo(double x, double y) { if(commands == null) { - commands = new ArrayList(); + commands = new ArrayList<>(); } int type = PathIterator.SEG_MOVETO; @@ -64,9 +65,8 @@ public void lineTo(double x, double y) { public void closePath() { azzertMoveTo(); - int type = PathIterator.SEG_CLOSE; - double[] coords = null; - commands.add(new Command(type, coords)); + Command closeCommand = new Command(PathIterator.SEG_CLOSE, null); + commands.add(closeCommand); } public void translate(double x, double y) { @@ -88,7 +88,7 @@ public void translate(double x, double y) { public String getD() { StringBuilder sb = new StringBuilder(); for(Command c : commands) { - sb.append(" " + c.toString()); + sb.append(" ").append(c.toString()); } if(sb.length() == 0) { return ""; @@ -102,6 +102,4 @@ public void buildString(StringBuilder sb, int level) { setAttribute("d", getD()); super.buildString(sb, level); } - - } diff --git a/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/PathIterator.java b/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/PathIterator.java index 5579aec5..fc0b95cc 100644 --- a/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/PathIterator.java +++ b/svglite/src/main/java/org/worldcubeassociation/tnoodle/svglite/PathIterator.java @@ -1,6 +1,6 @@ package org.worldcubeassociation.tnoodle.svglite; -import java.util.ArrayList; +import java.util.List; public class PathIterator { public static final int SEG_MOVETO = 0; @@ -10,7 +10,7 @@ public class PathIterator { public static final String SVG_LANGUAGE_COMMANDS = "MLTCZ"; private int index; - private ArrayList commands; + private final List commands; public PathIterator(Path p) { index = 0; commands = p.commands;