AttributeRecord[] (final int size, final int differentAttributesCount, final int maxAttributeValueSize, final Random rnd) { final int[] fileIds = rnd.ints() .filter(id -> id > 0) .limit(size / 2) .distinct() .toArray(); final int[] attributeIds = rnd.ints(0, AbstractAttributesStorage.MAX_ATTRIBUTE_ID + 1) .filter(id -> id > 0) .limit(differentAttributesCount) .distinct() .toArray(); return Stream.generate(() -> { final int fileId = fileIds[rnd.nextInt(fileIds.length)]; final int attributeId = attributeIds[rnd.nextInt(attributeIds.length)]; return new IntPair(fileId, attributeId); }) .distinct()//each (fileId,attributeId) pair should occurred only once! .limit(size) .map(pair -> { final int fileId = pair.first; final int attributeId = pair.second; return newAttributeRecord(fileId, attributeId) .withRandomAttributeBytes(rnd.nextInt(maxAttributeValueSize)); }).toArray(AttributeRecord[]::new); }