Для хранения продуктов используется словарь: ключ - атрибут, значение - множество id, в которых есть данный атрибут. Каждый атрибут продукта кладется в словарь как ключ, в значение - id продукта. При совпадении атрибутов у разных продуктов, в значение добавляется id нового продукта. Из словаря достаются значения по атрибуту. Итоговые id товаров - общие id по заданным атрибутам.
Ассимптотическая сложность поиска продуктов содержащих заданные атрибуты - O(n*m), где n - количество введенных в поиск атрибутов, m - количество товаров, содержащих данный атрибут.
mvn compile
mvn test - Провести все тесты
mvn -Dtest=ProductsStorageTest#put** test - Провести все тесты создания структуры
mvn -Dtest=ProductsStorageTest#search** test - Проверить все тесты поиска по атрибуту