В общем есть такой код:
private static final Map<Integer, Constrain<CharSequence>>
minLengthCache = new HashMap<>(),
maxLengthCache = new HashMap<>();
public static Constrain<CharSequence> minLength(int length) {
Constrain<CharSequence> cached = minLengthCache.get(length);
if (cached == null)
minLengthCache.put(length, cached = string -> string.length() > length);
return cached;
}
public static Constrain<CharSequence> maxLength(int length) {
Constrain<CharSequence> cached = maxLengthCache.get(length);
if (cached == null)
maxLengthCache.put(length, cached = string -> string.length() < length);
return cached;
}
Как видно, очень некрасиво повторяется. Что порождает кучу опасностей ошибиться при копипасте, а если таких функций будет штук 20 и нужно будет что-то поменять, то можно вообще об стенку убиться.
Первым делом приходит в голову нечто такое:
public static Constrain<CharSequence> minLength(int length) {
return cachedOrNew(string -> string.length() > length);
}
public static Constrain<CharSequence> cachedOrNew(Constrain<CharSequence> newObj) {
Constrain<CharSequence> cached = minLengthCache.get(length);
if (cached == null)
minLengthCache.put(length, cached = newObj);
return cached;
}
Но здесь теряется смысл в кэше совсем. Ведь каждый раз всё равно будет создаваться новый экземпляр объекта, а заодно и его класс, объекта, который должен быть возвращен, если в кэше такого нет.
В принципе я представляю, как это это решить через вложенный класс, .Class
и рефлексию, но тогда придется отказаться от очень удобного синтаксиса лямбда выражений.
В общем решил проблему вот так:
private interface ConstrainFactory<C, P> {
Constrain<C> create(P param);
}
private static <P, C> Constrain cachedOrNew(Map<P, Constrain<C>> cache, ConstrainFactory factory, P param) {
Constrain cached = cache.get(param);
if (cached == null)
cache.put(param, cached = factory.create(param));
return cached;
}
public static Constrain<CharSequence> minLength(int length) {
return cachedOrNew(minLengthCache, minLengthConstrain, length);
}
private static ConstrainFactory<String, Integer> minLengthConstrain = (length) -> (string) -> string.length() > length;
Всё решение основывается на том, что есть некий параметр, на основе которого можно генерировать классы. Для меня сойдет, но возможности лямбды по сути не используются, да и выглядит код своебразно - сразу и не въедешь, для чего что нужно. Поэтому вопрос оставляю открытым - может кто покрасивее предложит решение.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Нашел только getCaretPosition(), но это немного не то
Здравствуйте, пишу приложение на javaВ качестве GUI использую JavaFX (скажу сразу, что при использование swt данной проблемы нет)