Что такое хорошие шаблоны/методы для уменьшения многословия Java
Одна из вещей, которые могут быть немного раздражающими в отношении Java, - это объем кода, который вам нужен для выражения понятий. Я верю в философию "меньше кода лучше", и я хотел бы знать, как я могу писать Java, не будучи настолько расстраивающим многословным. Недавно я прочитал вопрос Скрытые особенности Java и был представлен для использования двойная привязка, чтобы имитировать листинг списка или карты. Конечно, есть недостатки в использовании этого метода, но это позволяет вам делать определенные вещи со значительно меньшим количеством символов и (если вы отформатируете их правильно), сделать код намного чище и понятнее. Мне интересно, нет ли других умных трюков и менее известных функций языка, которые могли бы сделать мой код более кратким.
Я хотел бы видеть ответы с объяснением техники, более подробным образом, который он заменяет, и любыми потенциальными недостатками в использовании техники.
Ответы
Ответ 1
До появления оператора алмаза в Java 7 статические методы factory для создания родовых типов могли быть использованы для уменьшения детализации, уменьшая необходимость повторения параметр типа. (Это связано с тем, что без оператора алмаза Java никогда не вводит параметр типа в конструкторы, но он будет обрабатывать вызовы методов.) Коллекции Google использует это техники, поэтому вы можете написать:
Set<MyClassWithALongName> set = Sets.newHashSet();
вместо:
Set<MyClassWithALongName> set = new HashSet<MyClassWithALongName>();
Посмотрите в классах Lists
, Sets
и Maps
коллекций Google для методов, начинающихся с "new" для получения дополнительных примеров.
Если вы не пишете старую версию Java, а с Java 7 лучше просто использовать оператор бриллианта.
Ответ 2
Аналогичный, о котором вы, вероятно, уже знаете, используя функцию "varargs":
String[] array = new String[] {"stack", "over", "flow"};
List<String> list = Arrays.asList(array);
может быть сокращено
List<String> list = Arrays.asList("stack", "over", "flow");
По правде говоря, это не огромная экономия, но это немного уменьшает многословие. Как отмечает Томас, список будет неизменным, поэтому следите за этим. Собственно, вы можете изменить список, вы просто не можете изменить его длину. Спасибо pimlottc за указание на это.
Ответ 3
Используйте инфраструктуру инъекции зависимостей, например spring. Я почти всегда поражаюсь тому, как создается логика построения кода.
Ответ 4
Я обнаружил, что наиболее эффективный способ писать сжатый java файл (только?) - это вообще не писать java. В тех случаях, когда мне нужно было что-то быстро написать, что все еще взаимодействует с Java, я нашел Groovy отличным выбором. Использование более сжатого языка, который по-прежнему компилируется в байт-код JVM, может быть отличным решением. Хотя у меня нет личного опыта в этом, я слышал, что Scala - это даже лучший выбор, чем Groovy во многих случаях.
Ответ 5
Проверьте lambdaj. Он имеет множество функций, которые могут помочь сделать ваш код более кратким и читаемым.
Ответ 6
Свободные интерфейсы могут помочь - используя сборщики и цепочку методов, чтобы сделать что-то похожее на DSL в java. Код, который вы в конечном итоге, может быть немного сложнее прочитать, поскольку он нарушает обычные правила кодирования Java, такие как удаление свойств set/get из свойств.
Итак, в фальшивом свободном интерфейсе Swing вы можете определить кнопку таким образом:
JButton button = Factory.button().icon(anIcon).tooltip("Wow").swing();
Другой подход заключается в использовании другого языка, многие из которых хорошо интегрируются с JVM, например:
Ответ 7
Метод "closeQuietly" может использоваться в блоках try/finally в ситуациях, когда исключения IO при закрытии неинтересны (или невозможны).
Closeable c = null;
try {
...
c = openIt(...);
...
} finally {
closeQuietly(c);
}
где:
/** Close 'c' if it is not null, squashing IOExceptions */
public void closeQuietly(Closeable c) {
if (c != null) {
try {
c.close();
} catch (IOException ex) {
// log error
}
}
}
Обратите внимание, что с помощью Java 7 и более поздних версий новый синтаксис "попробуйте с ресурсами" делает этот конкретный пример избыточным.
Ответ 8
Я нашел сообщение в блоге с интересной техникой, которая позволяет писать буквенный буклет в Java, как вы могли бы сделать в Perl, Python, Ruby и т.д.: Построение собственных литералов в Java - Кортежи и Карты
Мне очень нравится этот подход! Я просто подытожу его здесь.
Основная идея - создать общий парный класс и определить статические функции, которые будут строить пару, и карту из массива пар varargs. Это позволяет использовать следующее сжатое определение букв карты:
Map(o("height", 3), o("width", 15), o("weight", 27));
Где o
- это имя статической функции для создания пары объектов T1 и T2 для любых типов объектов T1 и T2, а Map
- это имя статической функции для построения Карты. Я не уверен, что мне нравится выбор Map
как имени функции построения карты, потому что он совпадает с именем интерфейса Java, но концепция по-прежнему хороша.
Ответ 9
Статические инициализаторы
Пример 1 (Карта):
Map<String, String> myMap = new HashMap<String, String>() {{
put ("a", "b");
put ("c", "d");
}};
Пример 2 (Список):
List<String> myList = new ArrayList<String>() {{
add("a");
add("b");
add("c");
}};
Ответ 10
Подробнее Guave goodness, чтобы инициализировать неизменяемые карты (которые я считаю более обычным случаем, чем инициализация изменчивых карт): ImmutableMap.of(...) варианты
Map<Service, Long> timeouts = ImmutableMap.of(
orderService, 1500,
itemService, 500);
Ответ 11
Вам нужно перебирать коллекцию, просто чтобы отобразить ее элементы по одному из своих свойств? Нет больше, благодаря Maps.uniqueIndex()
:
private void process(List<Module> modules) {
Map<String, Module> byName = Maps.uniqueIndex(modules, new Function<Module, String>() {
@Override public String apply(Module input) {
return input.getName();
}
});
или если это достаточно часто, сделайте функцию a public static final
членом Module
, чтобы приведенное выше было сведено к:
Map<String, Module> byName = Maps.uniqueIndex(modules, Module.KEY_FUNCTION);