Возникшая проблема не относится к задачам на образовательном портале JavaRush, но вызывает болезненный интерес длительный срок.
Задача:
У вас есть два Java массива A и В. Массивы не сортированные. Напишите функцию, которая максимально быстро найдет пересечение этих массивов (список элементов, которые есть в обоих массивах).
Стремление образовать универсальное решение, способное находить общие элементы любых типов, сталкивается с проблемой создания массива с конечным результатом работы. Использовал HashSet для сжатия значений, повторяющихся внутри входящих массивов, до единственного экземпляра. Количество совпадений считал через наличие "ключей" в HashMap. Если сравнивать элементы простым перебором "цикл в цикле", то временная сложность алгоритма, кажется, выходит О(n^2), картой же - O(n) .
Длительные поиски на просторах великого интернета указывали на потребность создания фабрик или применения рефлексии, но окончательно повергли в "темный лес". Буду признателен, если сможете указать и объяснить в общих чертах методику решения. Если, конечно же, оно может существовать как таковое.
public class Main <T extends Comparable>{
//Карта для хранения значений
private HashMap<T, Integer> vault = new HashMap<>();
public T[] compareData(T[] first, T[] second) {
List<T> result = new ArrayList<>();
/* Исключил повторение элементов в исходном массиве с помощью тонкостей HashSet
и заполнил карту функцией fillVault */
fillVault(new HashSet<>(Arrays.asList(first)));
fillVault(new HashSet<>(Arrays.asList(second)));
//Вывожу найденные совпадения в список
vault.forEach((key, value) -> {
if (value > 1)
result.add(key);
});
//Ошибка. Создание массива типа T не представляется возможным
return result.toArray(new T[result.size()]);
}
//Функция для заполнения карты
private void fillVault (HashSet<T> input) {
input.forEach(value -> {
if (!vault.containsKey(value))
vault.put(value, 1);
else
vault.put(value, vault.get(value) + 1);
});
}
public static void main(String[] args) {
}
}
UPD. Нашел способ, но довольно костыльный (признан таковым самими разработчиками Generic). Если присутствует нечто более элегантное, буду рад узнать.
result.toArray((T[]) new Object[result.size()])