From 6e7040b2456c27427758d3ae06d51b71c626cce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=BE=D0=BB=D0=BE=D0=B4=D0=B8=D0=BD=20=D0=93=D0=B5?= =?UTF-8?q?=D1=80=D0=BC=D0=B0=D0=BD?= Date: Tue, 1 Sep 2026 23:35:52 +0400 Subject: [PATCH] feat(random): generate students using streams - generate students with IntStream - collect generated students into MyList using MyListCollector - round average grade to two decimal places - extract student generation into a separate method --- .../random/RandomStudentGenerator.java | 189 ++++++++++++------ 1 file changed, 126 insertions(+), 63 deletions(-) diff --git a/app/src/main/java/ru/project/random/RandomStudentGenerator.java b/app/src/main/java/ru/project/random/RandomStudentGenerator.java index 5ed279e..3e3c705 100644 --- a/app/src/main/java/ru/project/random/RandomStudentGenerator.java +++ b/app/src/main/java/ru/project/random/RandomStudentGenerator.java @@ -1,53 +1,63 @@ package ru.project.random; -import ru.project.collection.MyLinkedList; -import ru.project.collection.MyList; -import ru.project.student.Student; + import java.util.Random; import java.util.regex.Pattern; +import java.util.stream.IntStream; +import ru.project.collection.MyList; +import ru.project.collectors.MyCollectors; +import ru.project.student.Student; import ru.project.student.StudentBuilder; -public class RandomStudentGenerator -{ - private static final Random RANDOM = new Random(); - private String minGroupNumber; - private String maxGroupNumber; - private Double minAverageGrade; - private Double maxAverageGrade; - private Integer minRecordBookNumber; - private Integer maxRecordBookNumber; - private static final double DEFAULT_MIN_GRADE = 0.0; - private static final double DEFAULT_MAX_GRADE = 5.0; - private static final int DEFAULT_MIN_RECORD_BOOK = 1; - private static final String GROUP_PATTERN_REGEX = "^[A-Z][0-9]{2}$"; - private static final Pattern GROUP_PATTERN = Pattern.compile(GROUP_PATTERN_REGEX); - public RandomStudentGenerator setMinGroupNumber(String minGroupNumber) { - if (minGroupNumber != null && !GROUP_PATTERN.matcher(minGroupNumber).matches()) { - throw new IllegalArgumentException("minGroupNumber does not match Student group pattern: " + GROUP_PATTERN_REGEX); - } - this.minGroupNumber = minGroupNumber; - return this; - } - public RandomStudentGenerator setMaxGroupNumber(String maxGroupNumber) { - if (maxGroupNumber != null && !GROUP_PATTERN.matcher(maxGroupNumber).matches()) { - throw new IllegalArgumentException("maxGroupNumber does not match Student group pattern: " + GROUP_PATTERN_REGEX); - } - this.maxGroupNumber = maxGroupNumber; - return this; + +public class RandomStudentGenerator { + + private static final Random RANDOM = new Random(); + + private String minGroupNumber; + private String maxGroupNumber; + + private Double minAverageGrade; + private Double maxAverageGrade; + + private Integer minRecordBookNumber; + private Integer maxRecordBookNumber; + + private static final double DEFAULT_MIN_GRADE = 0.0; + private static final double DEFAULT_MAX_GRADE = 5.0; + private static final int DEFAULT_MIN_RECORD_BOOK = 1; + + private static final String GROUP_PATTERN_REGEX = "^[A-Z][0-9]{2}$"; + private static final Pattern GROUP_PATTERN = Pattern.compile(GROUP_PATTERN_REGEX); + + public RandomStudentGenerator setMinGroupNumber(String minGroupNumber) { + + if (minGroupNumber != null && !GROUP_PATTERN.matcher(minGroupNumber).matches()) { + + throw new IllegalArgumentException( + "minGroupNumber does not match Student group pattern: " + GROUP_PATTERN_REGEX); } + this.minGroupNumber = minGroupNumber; + return this; } public RandomStudentGenerator setMaxGroupNumber(String maxGroupNumber) { + if (maxGroupNumber != null && !GROUP_PATTERN.matcher(maxGroupNumber).matches()) { + throw new IllegalArgumentException( "maxGroupNumber does not match Student group pattern: " + GROUP_PATTERN_REGEX); } + this.maxGroupNumber = maxGroupNumber; + return this; } public RandomStudentGenerator setMinAverageGrade(double minAverageGrade) { + if (minAverageGrade < DEFAULT_MIN_GRADE || minAverageGrade > DEFAULT_MAX_GRADE) { + throw new IllegalArgumentException( "minAverageGrade out of Student allowed range [" + DEFAULT_MIN_GRADE @@ -55,12 +65,16 @@ public class RandomStudentGenerator + DEFAULT_MAX_GRADE + "]"); } + this.minAverageGrade = minAverageGrade; + return this; } public RandomStudentGenerator setMaxAverageGrade(double maxAverageGrade) { + if (maxAverageGrade < DEFAULT_MIN_GRADE || maxAverageGrade > DEFAULT_MAX_GRADE) { + throw new IllegalArgumentException( "maxAverageGrade out of Student allowed range [" + DEFAULT_MIN_GRADE @@ -68,25 +82,33 @@ public class RandomStudentGenerator + DEFAULT_MAX_GRADE + "]"); } + this.maxAverageGrade = maxAverageGrade; + return this; } public RandomStudentGenerator setMinRecordBookNumber(int minRecordBookNumber) { + if (minRecordBookNumber < DEFAULT_MIN_RECORD_BOOK) { throw new IllegalArgumentException( "minRecordBookNumber must be >= " + DEFAULT_MIN_RECORD_BOOK); } + this.minRecordBookNumber = minRecordBookNumber; + return this; } public RandomStudentGenerator setMaxRecordBookNumber(int maxRecordBookNumber) { + if (maxRecordBookNumber < DEFAULT_MIN_RECORD_BOOK) { throw new IllegalArgumentException( "maxRecordBookNumber must be >= " + DEFAULT_MIN_RECORD_BOOK); } + this.maxRecordBookNumber = maxRecordBookNumber; + return this; } @@ -94,75 +116,116 @@ public class RandomStudentGenerator if (size < 0) { throw new IllegalArgumentException("size must be non-negative"); } + validateRanges(); - MyList result = new MyLinkedList<>(); - for (int i = 0; i < size; i++) { - String group = generateGroupNumber(); - double grade = generateAverageGrade(); - int recordBook = generateRecordBookNumber(); - Student student = - new StudentBuilder() - .setGroupNumber(group) - .setAverageGrade(grade) - .setRecordBookNumber(recordBook) - .build(); - - result.add(student); - } - return result; + return IntStream.range(0, size) + .mapToObj(i -> generateStudent()) + .collect(MyCollectors.toMyList()); } - private double generateAverageGrade() { - double min = (minAverageGrade != null) ? minAverageGrade : DEFAULT_MIN_GRADE; - double max = (maxAverageGrade != null) ? maxAverageGrade : DEFAULT_MAX_GRADE; - double range = max - min; - double grade = min + (range * RANDOM.nextDouble()); - return Math.round(grade * 100.0) / 100.0; + private Student generateStudent() { + String groupNumber = generateGroupNumber(); + + double averageGrade = generateAverageGrade(); + + int recordBookNumber = generateRecordBookNumber(); + + return new StudentBuilder() + .setGroupNumber(groupNumber) + .setAverageGrade(averageGrade) + .setRecordBookNumber(recordBookNumber) + .build(); + } + + private void validateRanges() { + double effectiveMinGrade = minAverageGrade != null ? minAverageGrade : DEFAULT_MIN_GRADE; + + double effectiveMaxGrade = maxAverageGrade != null ? maxAverageGrade : DEFAULT_MAX_GRADE; + + if (effectiveMinGrade > effectiveMaxGrade) { + throw new IllegalArgumentException("minAverageGrade cannot be greater than maxAverageGrade"); } - if (minGroupNumber != null && maxGroupNumber != null) { - if (minGroupNumber.compareTo(maxGroupNumber) > 0) { - throw new IllegalArgumentException("minGroupNumber cannot be greater than maxGroupNumber"); - } + + int effectiveMinRecord = + minRecordBookNumber != null ? minRecordBookNumber : DEFAULT_MIN_RECORD_BOOK; + + int effectiveMaxRecord = maxRecordBookNumber != null ? maxRecordBookNumber : Integer.MAX_VALUE; + + if (effectiveMaxRecord == Integer.MAX_VALUE) { + effectiveMaxRecord = effectiveMinRecord + 999_999; + } + + if (effectiveMinRecord > effectiveMaxRecord) { + throw new IllegalArgumentException( + "minRecordBookNumber cannot be greater than maxRecordBookNumber"); + } + + if (minGroupNumber != null + && maxGroupNumber != null + && minGroupNumber.compareTo(maxGroupNumber) > 0) { + + throw new IllegalArgumentException("minGroupNumber cannot be greater than maxGroupNumber"); } } private String generateGroupNumber() { - String min = (minGroupNumber != null) ? minGroupNumber : "A00"; - String max = (maxGroupNumber != null) ? maxGroupNumber : "Z99"; + String min = minGroupNumber != null ? minGroupNumber : "A00"; + + String max = maxGroupNumber != null ? maxGroupNumber : "Z99"; + char minLetter = min.charAt(0); char maxLetter = max.charAt(0); + int minDigit = Integer.parseInt(min.substring(1)); + int maxDigit = Integer.parseInt(max.substring(1)); + char letter = (char) (minLetter + RANDOM.nextInt((maxLetter - minLetter) + 1)); + int digit; + if (letter == minLetter && letter == maxLetter) { + digit = minDigit + RANDOM.nextInt((maxDigit - minDigit) + 1); + } else if (letter == minLetter) { + digit = minDigit + RANDOM.nextInt(100 - minDigit); + } else if (letter == maxLetter) { + digit = RANDOM.nextInt(maxDigit + 1); + } else { + digit = RANDOM.nextInt(100); } + return letter + String.format("%02d", digit); } private double generateAverageGrade() { - double min = (minAverageGrade != null) ? minAverageGrade : DEFAULT_MIN_GRADE; - double max = (maxAverageGrade != null) ? maxAverageGrade : DEFAULT_MAX_GRADE; + double min = minAverageGrade != null ? minAverageGrade : DEFAULT_MIN_GRADE; + + double max = maxAverageGrade != null ? maxAverageGrade : DEFAULT_MAX_GRADE; double range = max - min; - return min + (range * RANDOM.nextDouble()); + + double grade = min + (range * RANDOM.nextDouble()); + + return Math.round(grade * 100.0) / 100.0; } private int generateRecordBookNumber() { - int min = (minRecordBookNumber != null) ? minRecordBookNumber : DEFAULT_MIN_RECORD_BOOK; - int max = - (maxRecordBookNumber != null) ? maxRecordBookNumber : min + 999_999; // разумный максимум + int min = minRecordBookNumber != null ? minRecordBookNumber : DEFAULT_MIN_RECORD_BOOK; + + int max = maxRecordBookNumber != null ? maxRecordBookNumber : min + 999_999; + if (max < min) { max = min; } + return min + RANDOM.nextInt((max - min) + 1); } }