docs: public void shuffle(long seed) {
          // just skip shuffle if there's only 1 example
          if (numExamples() < 2)
              return;
  
          //note here we use the same seed with different random objects guaranteeing same order
  
          List<INDArray> arrays = new ArrayList<>();
          List<int[]> dimensions = new ArrayList<>();
  
          arrays.add(getFeatures());
          dimensions.add(ArrayUtil.range(1, getFeatures().rank()));
  
          arrays.add(getLabels());
          dimensions.add(ArrayUtil.range(1, getLabels().rank()));
  
          if (featuresMask != null) {
              arrays.add(getFeaturesMaskArray());
              dimensions.add(ArrayUtil.range(1, getFeaturesMaskArray().rank()));
          }
  
          if (labelsMask != null) {
              arrays.add(getLabelsMaskArray());
              dimensions.add(ArrayUtil.range(1, getLabelsMaskArray().rank()));
          }
  
          Nd4j.shuffle(arrays, new Random(seed), dimensions);
  
          //As per CpuNDArrayFactory.shuffle(List<INDArray> arrays, Random rnd, List<int[]> dimensions) and libnd4j transforms.h shuffleKernelGeneric
          if (exampleMetaData != null) {
              int[] map = ArrayUtil.buildInterleavedVector(new Random(seed), numExamples());
              ArrayUtil.shuffleWithMap(exampleMetaData, map);
          }
      }