package com.ewjordan.util.random; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.List; public class Shuffler { /** Shuffle a list in-place */ static public void shuffleInPlace(List<? extends Object> objects) { Collections.shuffle(objects); } static private List<Double> yankDoubles(List<? extends Object> objects, String fieldName) { try { List<Double> doubles = new ArrayList<Double>(objects.size()); for (Object o : objects) { Class<?> clazz = o.getClass(); Field field; field = clazz.getDeclaredField(fieldName); double dub = field.getDouble(o); doubles.add(dub); } return doubles; } catch (Exception e) { throw new RuntimeException(e); } } static private void putDoubles(List<Double> doubles, List<? extends Object> objects, String fieldName) { if (doubles.size() != objects.size()) { throw new IllegalArgumentException("Sizes of lists do not match."); } try { for (int i=0; i<objects.size(); ++i) { Object o = objects.get(i); Class<?> clazz = o.getClass(); Field field = clazz.getDeclaredField(fieldName); field.setDouble(o, doubles.get(i)); } } catch (Exception e) { throw new RuntimeException(e); } } static public void shuffleDoubleFieldInPlace(List<?> objects, String fieldName) { List<Double> pulled = yankDoubles(objects, fieldName); Collections.shuffle(pulled); putDoubles(pulled, objects, fieldName); } /** Extract a list of doubles from a list of objects, shuffle it, and return it as a double array */ static public double[] getShuffledDoubleFields(List<? extends Object> objects, String fieldName) { try { List<Double> doubles = yankDoubles(objects, fieldName); Collections.shuffle(doubles); double[] arr = new double[doubles.size()]; for (int i=0; i<doubles.size(); ++i) { arr[i] = doubles.get(i); } return arr; } catch (Exception e) { throw new RuntimeException(e); } } /* EXAMPLE USAGE BELOW */ static private void exampleShuffling() { List<TestClass> myList = new ArrayList<TestClass>(); myList.add(new TestClass(1.0,5.0)); myList.add(new TestClass(2.0,6.0)); myList.add(new TestClass(3.0,7.0)); myList.add(new TestClass(4.0,8.0)); System.out.println("Raw: "); TestClass.print(myList); System.out.println("Shuffled in place: "); shuffleInPlace(myList); TestClass.print(myList); double[] shuffledDoubles = getShuffledDoubleFields(myList, "x"); System.out.println("Shuffled xs: "); for (double d : shuffledDoubles) { System.out.println(d); } TestClass.print(myList); } static public void main(String[] args) { exampleShuffling(); } static final private class TestClass { double x, y; public TestClass(double x, double y) { this.x = x; this.y = y; } static public void print(List<TestClass> list) { for (TestClass c : list) { System.out.println(c.x + ", " + c.y); } } } }