Ярлык функционального программирования на Java

Java задняя часть Программа перевода самородков функциональное программирование

Используйте методы функционального программирования в своих программах на Java с декларативным мышлением.

Разработчики Java™ привыкли к императивному и объектно-ориентированному программированию, поскольку эти функции поддерживаются с момента первого выпуска языка Java. В Java 8 мы получили новый набор мощных функциональных возможностей и синтаксиса. Функциональное программирование существует уже несколько десятилетий и, как правило, является более кратким и выразительным, менее подверженным ошибкам и легче распараллеливаемым, чем объектно-ориентированное программирование. Таким образом, есть веские причины для внедрения функций функционального программирования в программы на Java. Тем не менее, при программировании с функциональными функциями требуются некоторые изменения в том, как вы проектируете свой код.

Об этой статье

Java 8 — это самое значительное обновление языка Java с момента его создания, и оно включает в себя так много новых функций, что вы можете задаться вопросом, с чего начать, чтобы узнать о нем. В этой серии автор и преподаватель Венкат Субраманиам предлагает идиоматический способ изучения Java 8. После краткого изучения вам предлагается переосмыслить обычное использование Java и соглашения, которые вы считаете само собой разумеющимися, постепенно интегрируя новые технологии и синтаксис в свои программы.

Я думаю, что программирование с декларативным мышлением, а не с императивным, облегчает переход к более функциональному стилю программирования. существуетJava 8 idioms seriesВ первой статье этой серии я объяснил сходства и различия между императивным, декларативным и функциональным стилями программирования. Затем я покажу вам, как использовать декларативное мышление для постепенной интеграции методов функционального программирования в ваши Java-программы.

Императивный стиль (процедурно-ориентированный)

Разработчики, обученные императивному стилю программирования, привыкли указывать программам, что и как делать. Вот простой пример:

Листинг 1. Метод findNemo, написанный в императивном стиле
import java.util.*;

public class FindNemo {
  public static void main(String[] args) {
    List<String> names = 
      Arrays.asList("Dory", "Gill", "Bruce", "Nemo", "Darla", "Marlin", "Jacques");

    findNemo(names);
  }                 
  
  public static void findNemo(List<String> names) {
    boolean found = false;
    for(String name : names) {
      if(name.equals("Nemo")) {
        found = true;
        break;
      }
    }
    
    if(found)
      System.out.println("Found Nemo");
    else
      System.out.println("Sorry, Nemo not found");
  }
}

методfindNemo()Сначала инициализируйте изменяемую переменнуюflag, также известные как переменные мусора. Разработчики часто дают некоторым переменным временное имя, например.f,t,tempпоказать, что их вообще не должно быть. В этом примере эти переменные должны быть названыfound.

Далее программа перебирает заданныйnamesList, каждый раз будет оцениваться, совпадает ли текущее пройденное значение со значением, которое необходимо сопоставить. В этом примере значение, которое необходимо сопоставить, равноNemo, если пройденное значение совпадает, программа установит флаг вtrueи выполните оператор управления потоком «break», чтобы выйти из цикла.

Это стиль программирования, наиболее знакомый большинству Java-разработчиков — программы в императивном стиле, так что вы можете определить каждый шаг программы: вы указываете программе перебирать каждый элемент, сравниваете его со значением, которое нужно найти, устанавливаете флаги и выпрыгиваете. цикл. Императивный стиль программирования дает вам полный контроль над программой, что иногда хорошо. Но, если посмотреть на это с другой стороны, вы выполняете много работы, которую машины могут выполнять сами по себе, и это неизбежно приведет к падению производительности. Так что иногда вы можете быть более продуктивным, делая меньше.

Декларативный стиль

Декларативное программирование означает, что вам все равно нужно указать программе, что делать, но вы можете оставить детали реализации базовой библиотеке. Давайте посмотрим на переписывание с использованием декларативного стиля программирования.Листинг 1серединаfindNemoчто происходит, когда метод:

Листинг 2. Метод findNemo, написанный в декларативном стиле
public static void findNemo(List<String> names) {
  if(names.contains("Nemo"))
    System.out.println("Found Nemo");
  else
    System.out.println("Sorry, Nemo not found");
}

Первое, что нужно отметить, это то, что в этой версии нет ненужных переменных. Вам также не нужно тратить энергию на перебор коллекции. Вместо этого вы просто используете встроенныйcontains()метод выполнения работы. Вам по-прежнему нужно сообщить программе, что делать и содержит ли коллекция искомое значение, но на этом этапе вы передали детали базовым методам.

В примере с императивным стилем программирования вы управляете потоком обхода, и программа может точно следовать инструкциям; в декларативном примере, пока программа выполняет работу, вам не нужно обращать внимание на то, как она работает на все.contains()Реализация метода может быть разной, но если результат соответствует вашим ожиданиям, вы им будете довольны. Меньше работы, чтобы получить тот же результат.

Научившись мыслить в стиле декларативного программирования, вы облегчите переход к более функциональному стилю программирования. Причина в том, что функциональный стиль программирования построен на декларативном стиле. Декларативный стиль мышления позволяет постепенно переходить от императивного программирования к функциональному программированию.

функциональный стиль программирования

Хотя программирование в функциональном стиле всегда является декларативным, простое использование декларативного программирования не эквивалентно функциональному программированию. Это связано с тем, что функциональное программирование сочетает в себе декларативное программирование с функциями высшего порядка. На рис. 1 показана взаимосвязь между императивным, декларативным и функциональным стилями программирования.

Рисунок 1. Связь между императивным, декларативным и функциональным стилями программирования

A logic diagram showing how the imperative, declarative, and functional programming styles differ and overlap.

Функции высшего порядка в Java

В Java вы можете передавать объекты в методы, создавать объекты в методах и возвращать объекты из методов. Вы также можете сделать то же самое с функциями. То есть вы можете передавать функции методам, создавать функции в методах и возвращать функции из методов.

при этих обстоятельствах,методявляется частью класса (статического или экземпляра), но функция может быть частью метода и не может быть намеренно связана с классом или экземпляром. Метод или функция, которая может получать, создавать или возвращать функцию, называетсяФункции высшего порядка.

Пример функционального программирования

Принятие нового стиля программирования требует изменения вашего отношения к программам. Это процесс, который начинается с упражнений на простых примерах и переходит к созданию более сложных программ.

Листинг 3. Карта в императивном стиле программирования
import java.util.*;

public class UseMap {
  public static void main(String[] args) {
    Map<String, Integer> pageVisits = new HashMap<>();            
    
    String page = "https://agiledeveloper.com";
    
    incrementPageVisit(pageVisits, page);
    incrementPageVisit(pageVisits, page);
    
    System.out.println(pageVisits.get(page));
  }
  
  public static void incrementPageVisit(Map<String, Integer> pageVisits, String page) {
    if(!pageVisits.containsKey(page)) {
       pageVisits.put(page, 0);
    }
    
    pageVisits.put(page, pageVisits.get(page) + 1);
  }
}

существуетЛистинг 3середина,main()функция создаетHashMapдля сохранения посещений сайта. в то же время,incrementPageVisit()Метод увеличивает счетчик каждого посещения данной страницы. Мы сосредоточимся на этом методе.

Написано в императивном стиле программирования.incrementPageVisit()метод: его работа состоит в том, чтобы увеличить счетчик для данной страницы и сохранить его вMapсередина. Метод не знает, имеет ли данная страница уже значение счетчика, поэтому он сначала проверяет, существует ли значение счетчика, и если нет, вставляет значение счетчика «0» для страницы. Затем получите этот счет, увеличьте его и сохраните новый счет вMapсередина.

Декларативное мышление требует, чтобы вы изменили дизайн своих методов с «как» на «что». когдаincrementPageVisit()При вызове метода вам необходимо инициализировать заданное значение счетчика страниц равным 1 или увеличить значение счетчика на 1. Этоwhat.

Поскольку вы программируете декларативно, следующим шагом будет поиск в библиотеках JDK чего-то, что выполняет эту работу и реализуетMapметоды интерфейса. Другими словами, вам нужно найти кого-то, кто знаеткакВстроенный метод для выполнения указанной вами задачи.

оказываетсяmerge()Метод очень подходит для вашей цели. В листинге 4 используется новый декларативный метод дляЛистинг 3серединаincrementPageVisit()метод модификации. Однако в этом случае вы не просто выбираете более разумный способ написания более декларативного стиля кода, потому чтоmerge()является функцией более высокого порядка. Итак, новый код на самом деле является хорошим примером функционального стиля:

Листинг 4. Карта в стиле функционального программирования
public static void incrementPageVisit(Map<String, Integer> pageVisits, String page) {
    pageVisits.merge(page, 1, (oldValue, value) -> oldValue + value); 
}

В листинге 4pageпередается в качестве первого параметраmerge(): значение, соответствующее ключу на карте, будет обновлено. Второй параметр используется как начальное значение,если Mapне существует в значении указанного ключа, то значение будет присвоеноMapЗначение, соответствующее средней клавише (в данном случае "1"). Третий параметр — это лямбда-выражение, которое принимает текущийMapВ качестве параметров используются значение, соответствующее средней клавише, и значение, соответствующее второму параметру в функции. Лямбда-выражение возвращает сумму своих аргументов, фактически увеличивая счетчик. (Примечание редактора: Спасибо Иштвану Ковачу за исправление ошибки кода)

будетЛистинг 4изincrementPageVisit()Единственная строка кода в методе такая же, какЛистинг 3Сравните несколько строк кода в . Несмотря на то чтоЛистинг 4Программа на — это пример функционального стиля программирования, но декларативное продумывание проблем помогает нам совершить скачок.

Суммировать

Использование методов и синтаксиса функционального программирования в программах на Java дает много преимуществ: код чище, выразительнее, содержит меньше движущихся частей, его легче распараллелить и, как правило, легче понять, чем объектно-ориентированный код. Задача сейчас состоит в том, как изменить свое мышление с императивного стиля программирования, знакомого большинству разработчиков, на декларативное мышление.

Хотя функциональное программирование не такое простое и прямолинейное, вы можете научиться сосредотачиваться на программах, которые хотите.делать чтовместоКак сделатьЭто огромный скачок вперед. Позволив низкоуровневой библиотеке функций управлять выполнением, вы постепенно получите интуитивное понимание функций более высокого порядка, используемых для создания модулей функционального программирования.

Если вы обнаружите ошибки в переводе или в других областях, требующих доработки, добро пожаловать наПрограмма перевода самородковВы также можете получить соответствующие бонусные баллы за доработку перевода и PR. начало статьиПостоянная ссылка на эту статьюЭто ссылка MarkDown этой статьи на GitHub.


Программа перевода самородковэто сообщество, которое переводит высококачественные технические статьи из Интернета сНаггетсДелитесь статьями на английском языке на . Охват контентаAndroid,iOS,внешний интерфейс,задняя часть,блокчейн,продукт,дизайн,искусственный интеллекти другие поля, если вы хотите видеть больше качественных переводов, пожалуйста, продолжайте обращать вниманиеПрограмма перевода самородков,официальный Вейбо,Знай колонку.