refactor: reorganize collection utilities and search imports

This commit is contained in:
2026-08-31 17:58:15 +04:00
parent b8f28830f7
commit a59d574c67
4 changed files with 165 additions and 163 deletions
@@ -1,15 +1,12 @@
package ru.project.collectors;
import java.util.stream.Collector;
import ru.project.collection.MyList;
public class MyCollectors
{
private MyCollectors() {
public class MyCollectors {
private MyCollectors() {}
}
public static <T> Collector<T, MyList<T>, MyList<T>> toMyList()
{
return new MyListCollector<>();
}
public static <T> Collector<T, MyList<T>, MyList<T>> toMyList() {
return new MyListCollector<>();
}
}
@@ -1,43 +1,41 @@
package ru.project.collectors;
import java.util.Collections;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collector;
public class MyListCollector <T> implements Collector<T, MyList<T>, MyList<T>>
{
@Override
public Supplier<MyList<T>> supplier()
{
return () -> new MyLinkedList<>();
}
import ru.project.collection.MyLinkedList;
import ru.project.collection.MyList;
@Override
public BiConsumer<MyList<T>, T> accumulator() {
public class MyListCollector<T> implements Collector<T, MyList<T>, MyList<T>> {
@Override
public Supplier<MyList<T>> supplier() {
return () -> new MyLinkedList<>();
}
return (list, element) -> list.add(element);
}
@Override
public BiConsumer<MyList<T>, T> accumulator() {
@Override
public BinaryOperator<MyList<T>> combiner() {
return (list1, list2) -> {
list1.addAll(list2);
return list1;
};
}
return (list, element) -> list.add(element);
}
@Override
public Function<MyList<T>, MyList<T>> finisher()
{
return list -> list;
}
@Override
public BinaryOperator<MyList<T>> combiner() {
return (list1, list2) -> {
list1.addAll(list2);
return list1;
};
}
@Override
public Set<Collector.Characteristics> characteristics() {
return java.util.Set.of(
Collector.Characteristics.IDENTITY_FINISH
);
}
@Override
public Function<MyList<T>, MyList<T>> finisher() {
return list -> list;
}
@Override
public Set<Collector.Characteristics> characteristics() {
return java.util.Set.of(Collector.Characteristics.IDENTITY_FINISH);
}
}
@@ -1,125 +1,132 @@
package ru.project.finder;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class StudentOccurrenceIndexFinder
{
public int[] findOccurrences(MyList<Student> students, Student target) {
if (students == null) {
throw new IllegalArgumentException();
}
if (target == null) {
throw new IllegalArgumentException();
}
if (students.isEmpty()) {
return new int[0];
}
int size = students.size();
int threadCount = calculateThreadCount(size);
int chunkSize = countChunkSize(size, threadCount);
import ru.project.collection.MyLinkedList;
import ru.project.collection.MyList;
import ru.project.student.Student;
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
MyList<Future<MyList<Integer>>> futures = new MyLinkedList<>();
public class StudentOccurrenceIndexFinder {
public int[] findOccurrences(MyList<Student> students, Student target) {
if (students == null) {
throw new IllegalArgumentException();
}
if (target == null) {
throw new IllegalArgumentException();
}
if (students.isEmpty()) {
return new int[0];
}
int size = students.size();
int threadCount = calculateThreadCount(size);
int chunkSize = countChunkSize(size, threadCount);
for (int i = 0; i < threadCount; i++) {
int fromIndex = i * chunkSize;
int toIndex = Math.min(fromIndex + chunkSize, size);
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
MyList<Future<MyList<Integer>>> futures = new MyLinkedList<>();
if (fromIndex >= toIndex) {
break;
}
for (int i = 0; i < threadCount; i++) {
int fromIndex = i * chunkSize;
int toIndex = Math.min(fromIndex + chunkSize, size);
final int start = fromIndex;
final int end = toIndex;
if (fromIndex >= toIndex) {
break;
}
Future<MyList<Integer>> future = executor.submit(() -> {
final int start = fromIndex;
final int end = toIndex;
Future<MyList<Integer>> future =
executor.submit(
() -> {
return findInRange(students, target, start, end);
});
futures.add(future);
});
futures.add(future);
}
MyList<Integer> allIndices = new MyLinkedList<>();
try {
for (int i = 0; i < futures.size(); i++) {
Future<MyList<Integer>> future = futures.get(i);
MyList<Integer> partialResult = future.get();
if (partialResult != null) {
for (int j = 0; j < partialResult.size(); j++) {
allIndices.add(partialResult.get(j));
}
}
MyList<Integer> allIndices = new MyLinkedList<>();
try {
for (int i = 0; i < futures.size(); i++) {
Future<MyList<Integer>> future = futures.get(i);
MyList<Integer> partialResult = future.get();
if (partialResult != null) {
for (int j = 0; j < partialResult.size(); j++) {
allIndices.add(partialResult.get(j));
}
}
}
} catch (Exception e) {
throw new RuntimeException("Ошибка при поиске", e);
} finally {
executor.shutdown();
}
sortList(allIndices);
int[] resultArray = new int[allIndices.size()];
for (int i = 0; i < allIndices.size(); i++) {
resultArray[i] = allIndices.get(i);
}
return resultArray;
}
} catch (Exception e) {
throw new RuntimeException("Ошибка при поиске", e);
} finally {
executor.shutdown();
}
private void sortList(MyList<Integer> list) {
if (list.size() <= 1) return;
sortList(allIndices);
MyList<Integer> sorted = new MyLinkedList<>();
for (int i = 0; i < list.size(); i++) {
int value = list.get(i);
int insertIndex = 0;
while (insertIndex < sorted.size()) {
if (sorted.get(insertIndex) > value) {
break;
}
insertIndex++;
}
MyList<Integer> temp = new MyLinkedList<>();
for (int k = 0; k < insertIndex; k++) {
temp.add(sorted.get(k));
}
temp.add(value);
for (int k = insertIndex; k < sorted.size(); k++) {
temp.add(sorted.get(k));
}
sorted = temp;
}
while (!list.isEmpty()) {
list.remove(0);
}
for (int i = 0; i < sorted.size(); i++) {
list.add(sorted.get(i));
}
int[] resultArray = new int[allIndices.size()];
for (int i = 0; i < allIndices.size(); i++) {
resultArray[i] = allIndices.get(i);
}
private int calculateThreadCount(int size) {
int processors = Runtime.getRuntime().availableProcessors();
return Math.min(processors, size);
}
return resultArray;
}
private int countChunkSize(int size, int threadCount) {
if (threadCount == 0) return 0;
return (size + threadCount - 1) / threadCount;
}
private void sortList(MyList<Integer> list) {
if (list.size() <= 1) return;
private MyList<Integer> findInRange(MyList<Student> students, Student target, int fromIndex, int toIndex) {
MyList<Integer> foundIndices = new MyLinkedList<>();
MyList<Integer> sorted = new MyLinkedList<>();
for (int i = fromIndex; i < toIndex; i++) {
Student current = students.get(i);
if (current != null && current.equals(target)) {
foundIndices.add(i);
}
for (int i = 0; i < list.size(); i++) {
int value = list.get(i);
int insertIndex = 0;
while (insertIndex < sorted.size()) {
if (sorted.get(insertIndex) > value) {
break;
}
insertIndex++;
}
return foundIndices;
MyList<Integer> temp = new MyLinkedList<>();
for (int k = 0; k < insertIndex; k++) {
temp.add(sorted.get(k));
}
temp.add(value);
for (int k = insertIndex; k < sorted.size(); k++) {
temp.add(sorted.get(k));
}
sorted = temp;
}
while (!list.isEmpty()) {
list.remove(0);
}
for (int i = 0; i < sorted.size(); i++) {
list.add(sorted.get(i));
}
}
private int calculateThreadCount(int size) {
int processors = Runtime.getRuntime().availableProcessors();
return Math.min(processors, size);
}
private int countChunkSize(int size, int threadCount) {
if (threadCount == 0) return 0;
return (size + threadCount - 1) / threadCount;
}
private MyList<Integer> findInRange(
MyList<Student> students, Student target, int fromIndex, int toIndex) {
MyList<Integer> foundIndices = new MyLinkedList<>();
for (int i = fromIndex; i < toIndex; i++) {
Student current = students.get(i);
if (current != null && current.equals(target)) {
foundIndices.add(i);
}
}
return foundIndices;
}
}
@@ -1,30 +1,30 @@
package ru.project.search;
import ru.project.list.MyList;
import ru.project.list.MyLinkedList;
import ru.project.collection.MyLinkedList;
import ru.project.collection.MyList;
import ru.project.student.Student;
public class StudentSearchService {
private final StudentSearchCriteria criteria;
private final StudentSearchCriteria criteria;
public StudentSearchService(StudentSearchCriteria criteria) {
if (criteria == null) {
throw new IllegalArgumentException("Criteria must not be null");
}
this.criteria = criteria;
public StudentSearchService(StudentSearchCriteria criteria) {
if (criteria == null) {
throw new IllegalArgumentException("Criteria must not be null");
}
this.criteria = criteria;
}
public MyList<Student> find(MyList<Student> students) {
if (students == null) {
return new MyLinkedList<>();
}
MyList<Student> result = new MyLinkedList<>();
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
if (criteria.matches(s)) {
result.add(s);
}
}
return result;
public MyList<Student> find(MyList<Student> students) {
if (students == null) {
return new MyLinkedList<>();
}
}
MyList<Student> result = new MyLinkedList<>();
for (int i = 0; i < students.size(); i++) {
Student s = students.get(i);
if (criteria.matches(s)) {
result.add(s);
}
}
return result;
}
}