Программирование на Java и Коллекции Eclipse в субботу вечером.
Вы когда-нибудь просто садились и пишете код?
Иногда мне просто нравится сесть перед своей IDE и написать код Java. Я не всегда знаю, что собираюсь написать, и если обнаружу, что не создаю ничего полезного, я просто брошу работу. В других случаях я обнаруживаю, что создаю что-то, что могло бы стать новым кодовым ката или потенциально новым полезным API.
В субботу вечером я начал писать код и решил, что хочу посмотреть, смогу ли я использовать примитивные API в Коллекциях Eclipse для быстрого и плавного создания алфавита с прописными и строчными буквами.
@Test public void alphabet() { var alphabet = IntInterval.fromTo('A', 'Z') .zipInt(IntInterval.fromTo('a', 'z')) .collect(i -> Strings.toCodePoints( i.getOne(), i.getTwo())) .makeString(","); Assert.assertEquals( "Aa,Bb,Cc,Dd,Ee,Ff,Gg,Hh,Ii,Jj,Kk,Ll,Mm,Nn," + "Oo,Pp,Qq,Rr,Ss,Tt,Uu,Vv,Ww,Xx,Yy,Zz", alphabet); }
Я изначально не так писал код. Я начал кодировать с JDK 8 с использованием промежуточных типов, а затем переключился на JDK 11, чтобы использовать var
. Исходная версия кода выглядела так.
@Test public void alphabet() { IntInterval uppercase = IntInterval.fromTo('A', 'Z'); IntInterval lowercase = IntInterval.fromTo('a', 'z'); ImmutableList<IntIntPair> pairs = uppercase.zipInt(lowercase); ImmutableList<CodePointAdapter> strings = pairs.collect(pair -> Strings.toCodePoints( pair.getOne(), pair.getTwo())); String alphabet = strings.makeString(","); Assert.assertEquals( "Aa,Bb,Cc,Dd,Ee,Ff,Gg,Hh,Ii,Jj,Kk,Ll,Mm,Nn," + "Oo,Pp,Qq,Rr,Ss,Tt,Uu,Vv,Ww,Xx,Yy,Zz", alphabet); }
После замены всех типов на var
код выглядел следующим образом.
IntelliJ помогает сделать вещи действительно ясными и простыми при использовании свободного стиля программирования в Java, показывая промежуточные типы справа. См. Текст, подчеркнутый зеленым цветом ниже. Использование JDK 11 здесь не имеет большого значения, поскольку var
всего на три символа короче, чем String
.
Свободные примитивы
Наличие свободного примитивного API делает кодирование с примитивными типами намного более увлекательным и продуктивным. В приведенных выше примерах я смог использовать IntInterval
для создания как прописных, так и строчных букв. Затем, используя метод zipInt
, я смог объединить два экземпляра IntInterval
в ImmutableList
из IntIntPair
. Затем я смог преобразовать IntIntPair
экземпляров в CodePointAdapter
экземпляры, используя метод сбора. CodePointAdapter
реализует интерфейс CharSequence
, который также реализуется классом String
в Java. Наконец, makeString(“,”)
создает разделенные запятыми String
, объединяющие все CodePointAdapter
экземпляры.
Здесь требовалось ограниченное количество боксов, когда мне приходилось создавать экземпляры IntIntPair
и CodePointAdapter
. Но мне ни разу не пришлось помещать какие-либо int
значения в их Integer
аналоги-оболочки, чтобы продолжить плавные вызовы.
Предпочтение ссылки на метод
Я предпочитаю ссылки на методы лямбдам в Java. Ссылки на методы часто более краткие, чем лямбды, и обычно самодокументируются. Мне пришлось использовать лямбда, чтобы преобразовать IntIntPair
в CodePointAdapter
с помощью Strings.toCodePoints
.
Интересно, стоит ли добавлять новый перегруженный метод toCodePoints
к классу Strings
, который принимает IntIntPair
в качестве параметра. Мне также интересно, стоит ли добавлять версию метода, которая также принимает IntIterable
. Прямо сейчас toCodePoints
принимает массив int
.
Вот как выглядел бы код, если бы я использовал ссылку на метод вместо лямбда. Я извлек код, содержащийся в лямбде, в метод под названием toCodePoints
. Я обнаружил, что в наши дни делаю это довольно часто.
Возможно, в следующий раз, когда я буду писать код в субботу вечером, я посмотрю, есть ли смысл добавить один или оба toCodePoints
служебных метода к классу Strings
в Eclipse Collections.
Воскресный вечер подходит для ведения блога и программирования
Я думал, что закончу писать блог в воскресенье вечером, но потом решил, что хочу попробовать дополнительное кодирование с использованием Java и Streams. Мне было любопытно посмотреть, смогу ли я придумать такое же плавное решение для создания алфавита в верхнем / нижнем регистре с использованием примитивных потоков Java. Мне не удалось сохранить все в одном беглом вызове, но это было лучшее решение, которое я мог придумать, используя только встроенные типы Java и API.
Последние мысли
В будущем я мог бы превратить эти примеры кода в новую ката кода для Eclipse Collections и Java Streams. А пока вот окончательные версии кода в виде необработанного текста, если вы хотите поэкспериментировать с API самостоятельно.
Версия коллекций Eclipse
@Test public void alphabet() { var alphabet = IntInterval.fromTo('A', 'Z') .zipInt(IntInterval.fromTo('a', 'z')) .collect(this::toCodePoints) .makeString(","); Assert.assertEquals( "Aa,Bb,Cc,Dd,Ee,Ff,Gg,Hh,Ii,Jj,Kk,Ll,Mm,Nn," + "Oo,Pp,Qq,Rr,Ss,Tt,Uu,Vv,Ww,Xx,Yy,Zz", alphabet); } private CodePointAdapter toCodePoints(IntIntPair pair) { return Strings.toCodePoints(pair.getOne(), pair.getTwo()); }
Версия Java Streams
@Test public void alphabetStream() { var upper = IntStream.rangeClosed('A', 'Z').toArray(); var lower = IntStream.rangeClosed('a', 'z').toArray(); var alphabet = IntStream.range(0, 26) .mapToObj(i -> new String(new int[]{upper[i], lower[i]}, 0, 2)) .collect(Collectors.joining(",")); Assert.assertEquals( "Aa,Bb,Cc,Dd,Ee,Ff,Gg,Hh,Ii,Jj,Kk,Ll,Mm,Nn," + "Oo,Pp,Qq,Rr,Ss,Tt,Uu,Vv,Ww,Xx,Yy,Zz", alphabet); }
Удачного кодирования!
Коллекции Eclipse открыты для взносов. Если вам нравится библиотека, вы можете сообщить нам об этом, отметив ее на GitHub.