diff --git a/task01/src/com/example/task01/Pair.java b/task01/src/com/example/task01/Pair.java index f6fb603b..4023c0de 100644 --- a/task01/src/com/example/task01/Pair.java +++ b/task01/src/com/example/task01/Pair.java @@ -1,5 +1,52 @@ package com.example.task01; -public class Pair { - // TODO напишите реализацию -} +import java.util.Objects; +import java.util.function.BiConsumer; + +public class Pair { + private final T first; + private final U second; + + // Закрытый конструктор + private Pair(T first, U second) { + this.first = first; + this.second = second; + } + + // Статический фабричный метод + public static Pair of(T first, U second) { + return new Pair<>(first, second); + } + + // Геттеры + public T getFirst() { + return first; + } + + public U getSecond() { + return second; + } + + // Метод ifPresent с типизированным BiConsumer + public void ifPresent(BiConsumer consumer) { + if (first != null && second != null) { + consumer.accept(first, second); + } + } + + // Переопределение equals + @Override + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null || getClass() != obj.getClass()) return false; + Pair pair = (Pair) obj; + return Objects.equals(first, pair.first) && + Objects.equals(second, pair.second); + } + + // Переопределение hashCode + @Override + public int hashCode() { + return Objects.hash(first, second); + } +} \ No newline at end of file diff --git a/task01/src/com/example/task01/Task01Main.java b/task01/src/com/example/task01/Task01Main.java index 54dde94f..1e4c92c8 100644 --- a/task01/src/com/example/task01/Task01Main.java +++ b/task01/src/com/example/task01/Task01Main.java @@ -6,9 +6,6 @@ public class Task01Main { public static void main(String[] args) throws IOException { - // TODO С корректно реализованным классом Pair должен компилироваться и успешно работать следующий код: - - /* Pair pair = Pair.of(1, "hello"); Integer i = pair.getFirst(); // 1 String s = pair.getSecond(); // "hello" @@ -21,7 +18,7 @@ public static void main(String[] args) throws IOException { Pair pair2 = Pair.of(1, "hello"); boolean mustBeTrue = pair.equals(pair2); // true! boolean mustAlsoBeTrue = pair.hashCode() == pair2.hashCode(); // true! - */ + } diff --git a/task02/src/com/example/task02/SavedList.java b/task02/src/com/example/task02/SavedList.java index 6b3a037d..420a6427 100644 --- a/task02/src/com/example/task02/SavedList.java +++ b/task02/src/com/example/task02/SavedList.java @@ -1,35 +1,96 @@ package com.example.task02; -import java.io.File; -import java.io.Serializable; +import java.io.*; +import java.util.ArrayList; import java.util.AbstractList; public class SavedList extends AbstractList { + private final File file; + private final ArrayList list; public SavedList(File file) { + this.file = file; + this.list = loadFromFile(); + } + + @SuppressWarnings("unchecked") + private ArrayList loadFromFile() { + // Если файл не существует, возвращаем пустой список + if (!file.exists()) { + return new ArrayList<>(); + } + + try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file))) { + // Читаем объект из файла и приводим к нужному типу + Object obj = ois.readObject(); + return (ArrayList) obj; + } catch (IOException | ClassNotFoundException e) { + // Если произошла ошибка чтения, возвращаем пустой список + return new ArrayList<>(); + } + } + + private void saveToFile() { + try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) { + // Сохраняем текущее состояние списка в файл + oos.writeObject(list); + } catch (IOException e) { + throw new RuntimeException("Failed to save list to file", e); + } } @Override public E get(int index) { - return null; + return list.get(index); } @Override public E set(int index, E element) { - return null; + E previous = list.set(index, element); + saveToFile(); // Сохраняем после изменения + return previous; } @Override public int size() { - return 0; + return list.size(); } @Override public void add(int index, E element) { + list.add(index, element); + saveToFile(); // Сохраняем после добавления } @Override public E remove(int index) { - return null; + E removed = list.remove(index); + saveToFile(); // Сохраняем после удаления + return removed; + } + + // Переопределяем дополнительные методы для обеспечения сохранения + @Override + public boolean add(E element) { + boolean result = list.add(element); + if (result) { + saveToFile(); + } + return result; + } + + @Override + public void clear() { + list.clear(); + saveToFile(); + } + + @Override + public boolean remove(Object o) { + boolean result = list.remove(o); + if (result) { + saveToFile(); + } + return result; } -} +} \ No newline at end of file diff --git a/task03/src/com/example/task03/Task03Main.java b/task03/src/com/example/task03/Task03Main.java index 7f255e98..261a93e1 100644 --- a/task03/src/com/example/task03/Task03Main.java +++ b/task03/src/com/example/task03/Task03Main.java @@ -1,24 +1,104 @@ package com.example.task03; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; import java.nio.charset.Charset; -import java.util.List; -import java.util.Set; +import java.util.*; public class Task03Main { public static void main(String[] args) throws IOException { - List> anagrams = findAnagrams(new FileInputStream("task03/resources/singular.txt"), Charset.forName("windows-1251")); for (Set anagram : anagrams) { System.out.println(anagram); } - } public static List> findAnagrams(InputStream inputStream, Charset charset) { - return null; + // Читаем все слова из потока + List words = readWords(inputStream, charset); + + // Создаем мапу для группировки анаграмм + Map> anagramGroups = new HashMap<>(); + + // Обрабатываем каждое слово + for (String word : words) { + // Приводим к нижнему регистру + String lowerWord = word.toLowerCase(); + + // Проверяем условия фильтрации + if (!isValidWord(lowerWord)) { + continue; + } + + // Создаем ключ-сигнатуру (отсортированные буквы) + String signature = getSignature(lowerWord); + + // Добавляем слово в соответствующую группу + anagramGroups + .computeIfAbsent(signature, k -> new TreeSet<>()) + .add(lowerWord); + } + + // Фильтруем и сортируем результаты + return prepareResult(anagramGroups); + } + + private static List readWords(InputStream inputStream, Charset charset) { + List words = new ArrayList<>(); + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, charset))) { + String line; + while ((line = reader.readLine()) != null) { + String word = line.trim(); + if (!word.isEmpty()) { + words.add(word); + } + } + } catch (IOException e) { + throw new RuntimeException("Error reading input stream", e); + } + + return words; + } + + private static boolean isValidWord(String word) { + // Проверяем длину слова + if (word.length() < 3) { + return false; + } + + // Проверяем, что слово состоит только из русских букв + if (!word.matches("[а-яё]+")) { + return false; + } + + return true; + } + + private static String getSignature(String word) { + // Преобразуем слово в массив символов и сортируем + char[] chars = word.toCharArray(); + Arrays.sort(chars); + return new String(chars); + } + + private static List> prepareResult(Map> anagramGroups) { + List> result = new ArrayList<>(); + + // Отбираем только группы с 2+ словами + for (TreeSet group : anagramGroups.values()) { + if (group.size() >= 2) { + result.add(group); + } + } + + // Сортируем группы по первому слову + result.sort((group1, group2) -> { + String first1 = group1.iterator().next(); + String first2 = group2.iterator().next(); + return first1.compareTo(first2); + }); + + return result; } -} +} \ No newline at end of file