refactor: reorganize collection utilities and search imports
This commit is contained in:
@@ -1,15 +1,12 @@
|
|||||||
package ru.project.collectors;
|
package ru.project.collectors;
|
||||||
|
|
||||||
import java.util.stream.Collector;
|
import java.util.stream.Collector;
|
||||||
|
import ru.project.collection.MyList;
|
||||||
|
|
||||||
public class MyCollectors
|
public class MyCollectors {
|
||||||
{
|
private 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;
|
package ru.project.collectors;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.BinaryOperator;
|
import java.util.function.BinaryOperator;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collector;
|
import java.util.stream.Collector;
|
||||||
public class MyListCollector <T> implements Collector<T, MyList<T>, MyList<T>>
|
import ru.project.collection.MyLinkedList;
|
||||||
{
|
import ru.project.collection.MyList;
|
||||||
@Override
|
|
||||||
public Supplier<MyList<T>> supplier()
|
|
||||||
{
|
|
||||||
return () -> new MyLinkedList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
public class MyListCollector<T> implements Collector<T, MyList<T>, MyList<T>> {
|
||||||
public BiConsumer<MyList<T>, T> accumulator() {
|
@Override
|
||||||
|
public Supplier<MyList<T>> supplier() {
|
||||||
|
return () -> new MyLinkedList<>();
|
||||||
|
}
|
||||||
|
|
||||||
return (list, element) -> list.add(element);
|
@Override
|
||||||
}
|
public BiConsumer<MyList<T>, T> accumulator() {
|
||||||
|
|
||||||
@Override
|
return (list, element) -> list.add(element);
|
||||||
public BinaryOperator<MyList<T>> combiner() {
|
}
|
||||||
return (list1, list2) -> {
|
|
||||||
list1.addAll(list2);
|
|
||||||
return list1;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Function<MyList<T>, MyList<T>> finisher()
|
public BinaryOperator<MyList<T>> combiner() {
|
||||||
{
|
return (list1, list2) -> {
|
||||||
return list -> list;
|
list1.addAll(list2);
|
||||||
}
|
return list1;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Collector.Characteristics> characteristics() {
|
public Function<MyList<T>, MyList<T>> finisher() {
|
||||||
return java.util.Set.of(
|
return list -> list;
|
||||||
Collector.Characteristics.IDENTITY_FINISH
|
}
|
||||||
);
|
|
||||||
}
|
@Override
|
||||||
|
public Set<Collector.Characteristics> characteristics() {
|
||||||
|
return java.util.Set.of(Collector.Characteristics.IDENTITY_FINISH);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,125 +1,132 @@
|
|||||||
package ru.project.finder;
|
package ru.project.finder;
|
||||||
|
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
public class StudentOccurrenceIndexFinder
|
import ru.project.collection.MyLinkedList;
|
||||||
{
|
import ru.project.collection.MyList;
|
||||||
public int[] findOccurrences(MyList<Student> students, Student target) {
|
import ru.project.student.Student;
|
||||||
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);
|
|
||||||
|
|
||||||
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
|
public class StudentOccurrenceIndexFinder {
|
||||||
MyList<Future<MyList<Integer>>> futures = new MyLinkedList<>();
|
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++) {
|
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
|
||||||
int fromIndex = i * chunkSize;
|
MyList<Future<MyList<Integer>>> futures = new MyLinkedList<>();
|
||||||
int toIndex = Math.min(fromIndex + chunkSize, size);
|
|
||||||
|
|
||||||
if (fromIndex >= toIndex) {
|
for (int i = 0; i < threadCount; i++) {
|
||||||
break;
|
int fromIndex = i * chunkSize;
|
||||||
}
|
int toIndex = Math.min(fromIndex + chunkSize, size);
|
||||||
|
|
||||||
final int start = fromIndex;
|
if (fromIndex >= toIndex) {
|
||||||
final int end = 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);
|
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 {
|
} catch (Exception e) {
|
||||||
for (int i = 0; i < futures.size(); i++) {
|
throw new RuntimeException("Ошибка при поиске", e);
|
||||||
Future<MyList<Integer>> future = futures.get(i);
|
} finally {
|
||||||
MyList<Integer> partialResult = future.get();
|
executor.shutdown();
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sortList(MyList<Integer> list) {
|
sortList(allIndices);
|
||||||
if (list.size() <= 1) return;
|
|
||||||
|
|
||||||
MyList<Integer> sorted = new MyLinkedList<>();
|
int[] resultArray = new int[allIndices.size()];
|
||||||
|
for (int i = 0; i < allIndices.size(); i++) {
|
||||||
for (int i = 0; i < list.size(); i++) {
|
resultArray[i] = allIndices.get(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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int calculateThreadCount(int size) {
|
return resultArray;
|
||||||
int processors = Runtime.getRuntime().availableProcessors();
|
}
|
||||||
return Math.min(processors, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int countChunkSize(int size, int threadCount) {
|
private void sortList(MyList<Integer> list) {
|
||||||
if (threadCount == 0) return 0;
|
if (list.size() <= 1) return;
|
||||||
return (size + threadCount - 1) / threadCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MyList<Integer> findInRange(MyList<Student> students, Student target, int fromIndex, int toIndex) {
|
MyList<Integer> sorted = new MyLinkedList<>();
|
||||||
MyList<Integer> foundIndices = new MyLinkedList<>();
|
|
||||||
|
|
||||||
for (int i = fromIndex; i < toIndex; i++) {
|
for (int i = 0; i < list.size(); i++) {
|
||||||
Student current = students.get(i);
|
int value = list.get(i);
|
||||||
if (current != null && current.equals(target)) {
|
int insertIndex = 0;
|
||||||
foundIndices.add(i);
|
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;
|
package ru.project.search;
|
||||||
|
|
||||||
import ru.project.list.MyList;
|
import ru.project.collection.MyLinkedList;
|
||||||
import ru.project.list.MyLinkedList;
|
import ru.project.collection.MyList;
|
||||||
import ru.project.student.Student;
|
import ru.project.student.Student;
|
||||||
|
|
||||||
public class StudentSearchService {
|
public class StudentSearchService {
|
||||||
private final StudentSearchCriteria criteria;
|
private final StudentSearchCriteria criteria;
|
||||||
|
|
||||||
public StudentSearchService(StudentSearchCriteria criteria) {
|
public StudentSearchService(StudentSearchCriteria criteria) {
|
||||||
if (criteria == null) {
|
if (criteria == null) {
|
||||||
throw new IllegalArgumentException("Criteria must not be null");
|
throw new IllegalArgumentException("Criteria must not be null");
|
||||||
}
|
|
||||||
this.criteria = criteria;
|
|
||||||
}
|
}
|
||||||
|
this.criteria = criteria;
|
||||||
|
}
|
||||||
|
|
||||||
public MyList<Student> find(MyList<Student> students) {
|
public MyList<Student> find(MyList<Student> students) {
|
||||||
if (students == null) {
|
if (students == null) {
|
||||||
return new MyLinkedList<>();
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user