java передача функции в качестве параметра
Как передать функцию в качестве параметра в Java? [дубликат]
этот вопрос уже есть ответ здесь:
можно ли передать метод в метод Java в качестве параметра? Если да, может кто-нибудь, пожалуйста, направлять меня? Это не кажется тривиальным
8 ответов:
Java 8 и выше
использование лямбда-выражений Java 8+, Если у вас есть класс или интерфейс только с одним методом, например:
потом в любом месте, где используется MyInterface, вы можете заменить лямбда-выражение:
например, вы можете создать новый поток очень быстро:
и с помощью синтаксис ссылки на метод чтобы сделать его еще уборщик:
без лямбда-выражения, эти два последних примера будут выглядеть так:
Перед Java 8
этот шаблон известен как Команда.
имейте в виду, что вам лучше всего создать интерфейс для вашего конкретного использования. Если вы решили пойти с callable, то вы замените T выше с любым типом возвращаемого значения, которое вы ожидаете, например String.
в ответ на ваш комментарий ниже, можно сказать:
затем назовите его, возможно, используя анонимный внутренний класс:
имейте в виду, что это не трюк. Это просто базовый концептуальный эквивалент java для указателей функций.
для этого можно использовать отражение Java. Метод будет представлен в виде экземпляра java.ленг.отражать.Метод.
Лямбда-Выражения
синтаксис лямбда-выражений
лямбда-выражение состоит из следующего:
A разделенный запятыми список формальных параметров, заключенный в круглые скобки. В CheckPerson.метод испытания содержит один параметр, p, который представляет собой экземпляр класса человек.
Примечание: ты можно опустить тип данных параметров в лямбда-выражении. В кроме того, вы можете опустить скобки, если есть только один параметр. Например, также допустимо следующее лямбда-выражение:
тело, которое состоит из одного выражения или блока выражений. В этом примере используется следующее выражение:
если вы укажете одно выражение, то среда выполнения Java вычисляет выражение и возвращает его значение. Альтернативно, вы можете использовать оператор return:
оператор return не является выражением; в лямбда-выражении необходимо заключать операторы в фигурные скобки (<>). Тем не менее, у вас нет чтобы заключить вызов метода void в фигурные скобки. Например, ниже приведено допустимое лямбда-выражение:
обратите внимание, что лямбда-выражение очень похоже на объявление метода ; лямбда-выражения можно рассматривать как анонимные методы-методы без имени.
вот как вы можете «передать метод», используя лямбда-выражение:
приведенный выше пример можно сократить еще больше, используя :: оператор.
благодаря Java 8 вам не нужно делать следующие шаги, чтобы передать функцию в метод, вот для чего нужны лямбды, см. учебник лямбда-выражения Oracle. Остальная часть этого поста описывает то, что нам приходилось делать в старые добрые времена, чтобы реализовать эту функциональность.
обычно вы объявляете свой метод как принимающий некоторый интерфейс с одним методом, а затем передаете объект, который реализует этот интерфейс. Пример находится в commons-collections, где у вас есть интерфейсы для замыкания, трансформатора и предиката, а также методы, в которые вы передаете их реализации. Guava-это новые улучшенные commons-коллекции, вы можете найти там эквивалентные интерфейсы.
Так, например, commons-collections имеет org.апаш.палата общин.коллекции.CollectionUtils, который имеет множество статических методов, которые принимают объекты, переданные в, чтобы выбрать один наугад, есть один называется существует с этой сигнатурой:
Он принимает объект что реализует интерфейс предикат, который означает, что он должен иметь метод, который принимает объект и возвращает логическое значение.
Так я могу назвать это так:
и это возвращает true или false в зависимости от того, someCollection содержит объект, для которого предикат возвращает значение true.
В любом случае, это всего лишь пример, и commons-collections устарел. Я просто забыл эквивалент в гуаве.
Java поддерживает закрытие просто отлично. Он просто не поддерживает функции, поэтому синтаксис, к которому вы привыкли для замыканий, гораздо более неудобен и громоздок: вы должны обернуть все в класс с помощью метода. Например,
вернет запускаемый объект, который run() метод «закрывает» x передано, как и в любом языке, который поддерживает первоклассные функции и замыкания.
я использовал шаблон команды, который @jk. упомянуто, добавив тип возврата:
Java: передача параметров по значению или по ссылке
Простое объяснение принципов передачи параметров в Java.
Многие программисты часто путают, какие параметры в Java передаются по значению, а какие по ссылке. Давайте визуализируем этот процесс, и тогда вы увидите насколько все просто.
Данные передаются между методами через параметры. Есть два способа передачи параметров:
Передача по значению (by value). Значения фактических параметров копируются. Вызываемый метод создает свою копию значений аргументов и затем ее использует. Поскольку работа ведется с копией, на исходный параметр это никак не влияет.
Передача по ссылке (by reference). Параметры передаются как ссылка (адрес) на исходную переменную. Вызываемый метод не создает свою копию, а ссылается на исходное значение. Следовательно, изменения, сделанные в вызываемом методе, также будут отражены в исходном значении.
В Java переменные хранятся следующим образом:
Локальные переменные, такие как примитивы и ссылки на объекты, создаются в стеке.
Объекты — в куче (heap).
Теперь вернемся к основному вопросу: переменные передаются по значению или по ссылке?
Java всегда передает параметры по значению
Чтобы разобраться с этим, давайте посмотрим на пример.
Пример передачи примитивов по значению
Поскольку Java передает параметры по значению, метод processData работает с копией данных. Следовательно, в исходных данных (в методе main ) не произошло никаких изменений.
Теперь рассмотрим другой пример:
Передача объекта
Что здесь происходит? Если Java передает параметры по значению, то почему был изменен исходный список? Похоже, что Java все-таки передает параметры не по значению? Нет, неправильно. Повторяйте за мной: «Java всегда передает параметры по значению».
Чтобы с этим разобраться, давайте посмотрим на следующую диаграмму.
Память стека (stack) и кучи (heap)
Давайте посмотрим на еще один пример:
Передача объекта по ссылке
Память стека (stack) и кучи (heap)
Итак, Java всегда передает параметры по значению. Однако мы должны быть осторожны при передаче ссылок на объекты.
Вышеприведенная концепция очень важна для правильного решения ваших задач.
Например, рассмотрим удаление узла в односвязном списке.
Удаление узла в связанном списке
Это решение работает во всех случаях, кроме одного — когда вы удаляете первый узел ( Position = 1 ). Основываясь на ранее описанной концепции, видите ли вы в чем здесь проблема? Возможно, поможет следующая диаграмма.
Удаление первого узла односвязного списка
Для исправления алгоритма необходимо сделать следующее:
В этой статье мы обсудили одну небольшую, но важную концепцию Java: передачу параметров.
Подробнее о курсе и программе обучения можно узнать на бесплатном вебинаре, который пройдет 15 апреля.
Передача функции в качестве параметра в java
Я знакомлюсь с Android framework и Java и хотел создать общий класс «NetworkHelper», который будет обрабатывать большую часть сетевого кода, позволяющего мне просто вызывать веб-страницы из него.
Я следил за этой статьей из developer.android.com чтобы создать мой сетевой класс:http://developer.android.com/training/basics/network-ops/connecting.html
В моем классе активности я использую класс такой:
проблема, с которой я сталкиваюсь, заключается в том, что я должен каким-то образом сделать обратный вызов активности, и он должен быть определен в функции «downloadUrl ()». Например, когда загрузка заканчивается, функция public void «handleWebpage (String data)» в activity вызывается с загруженной строкой в качестве ее параметра.
Я сделал некоторые googling и обнаружил, что я должен каким-то образом использовать интерфейсы для достижения этой функциональности. После рассмотрения нескольких похожие вопросы/ответы stackoverflow я не получил его, и я не уверен, что правильно понял интерфейсы:как передать метод в качестве параметра в Java? честно говоря, использование анонимных классов является новым для меня, и я не совсем уверен, где и как я должен применять фрагменты кода примера в упомянутом потоке.
Итак, мой вопрос в том, как я могу передать функцию обратного вызова в свой сетевой класс и вызвать ее после завершения загрузки? Где интерфейс объявление идет, реализует ключевое слово и так далее? Обратите внимание, что я новичок с Java (есть другой фон программирования, хотя), поэтому я был бы признателен за объяснение:) спасибо!
6 ответов
использовать интерфейс обратного вызова или абстрактный класс с абстрактными методами обратного вызова.
пример интерфейса обратного вызова:
второй вариант еще более лаконичен. Вам даже не нужно определять абстрактный метод для «ondownloaded event» как onPostExecute делает именно то, что нужно. Просто расширьте свой DownloadWebpageTask С анонимным встроенным классом внутри вашего downloadUrl метод.
да, интерфейс-лучший способ IMHO. Например, GWT использует шаблон команды с таким интерфейсом:
таким образом, вы можете передать функцию из метода к другому
выходное решение заключается в том, что это невозможно в Java. Java не принимает функции более высокого порядка. Это может быть достигнуто, хотя и с помощью некоторых «трюков». Обычно интерфейс используется так, как вы видели. Пожалуйста, посмотрите здесь для получения дополнительной информации. Вы также можете использовать отражение для его достижения, но это подвержено ошибкам.
нет интерфейса, нет lib, нет Java 8 не требуется!
просто используя Callable С java.util.concurrent
как использовать:
здесь myParamMethod() наш переданный метод как параметр (в этом случае methodParam ).
использование интерфейсов может быть лучшим способом в архитектуре кодирования Java.
но передача объекта Runnable также может работать, и это было бы намного практичнее и гибче, я думаю.
Как передать функцию в качестве параметра в Java? [дубликат]
этот вопрос уже есть ответ здесь:
можно ли передать метод в метод Java в качестве параметра? Если да, то кто-нибудь может меня проводить? Это не кажется тривиальным
8 ответов
Java 8 и выше
используя Java 8+ лямбда-выражения, если у вас есть класс или интерфейс только с одним методом, например:
потом в любом месте, где используется MyInterface, вы можете заменить лямбда-выражение:
например, вы можете создать новый поток очень быстро:
и с помощью синтаксис ссылки на метод чтобы сделать его еще уборщик:
без лямбда-выражения, эти последние два примера будет выглядеть так:
Перед Java 8
этот шаблон известен как Команда.
имейте в виду, что вам лучше всего создать интерфейс для вашего конкретного использования. Если вы решили пойти с callable, то вы замените T выше любым типом возвращаемого значения, которое вы ожидаете, например String.
в ответ на ваш комментарий ниже, можно сказать:
затем вызовите его, возможно, используя анонимный внутренний класс:
имейте в виду, что это не трюк. Это просто базовый концептуальный эквивалент java для указателей функций.
для этого можно использовать отражение Java. Метод будет представлен как экземпляр java.ленг.отражать.Метод.
Лямбда-Выражения
синтаксис лямбда-выражений
лямбда-выражение состоит из следующего:
A разделенный запятыми список формальных параметров, заключенный в круглые скобки. В CheckPerson.метод теста содержит один параметр, p, который представляет собой экземпляр класса человек.
Примечание: ты можно опустить тип данных параметров в лямбда-выражении. В кроме того, вы можете опустить скобки, если есть только один параметр. Например, также допустимо следующее лямбда-выражение:
тело, которое состоит из одного выражения или блока выражений. В этом примере используется следующее выражение:
если указать одно выражение, то среда выполнения Java вычисляет выражение и возвращает его значение. Альтернативно, вы можете использовать оператор return:
оператор return не является выражением; в лямбда-выражении необходимо заключить операторы в фигурные скобки (<>). Однако у вас нет заключать вызов метода void в фигурные скобки. Например, ниже приведено допустимое лямбда-выражение:
обратите внимание, что лямбда-выражение очень похоже на объявление метода ; лямбда-выражения можно рассматривать как анонимные методы-методы без имени.
вот как вы можете «передать метод», используя лямбда-выражение:
приведенный выше пример можно сократить еще больше, используя :: оператор.
благодаря Java 8 вам не нужно делать следующие шаги, чтобы передать функцию методу, вот для чего предназначены лямбды, см. лямбда-выражение Oracle учебник. Остальная часть этого сообщения описывает, что нам приходилось делать в старые добрые времена, чтобы реализовать эту функциональность.
обычно вы объявляете свой метод как принимающий некоторый интерфейс с одним методом, а затем передаете объект, который реализует этот интерфейс. Пример находится в commons-collections, где у вас есть интерфейсы для замыкания, трансформатора и предиката и методы, в которые вы передаете реализации этих. Guava-это новые улучшенные общие коллекции, вы можете найти там эквивалентные интерфейсы.
Так, например, commons-collections имеет org.апаш.палата общин.коллекции.CollectionUtils, который имеет множество статических методов, которые принимают переданные объекты, чтобы выбрать один наугад, есть один, называемый exists с этой сигнатурой:
Он принимает объект это реализует предикат интерфейса, что означает, что на нем должен быть метод, который принимает некоторый объект и возвращает логическое значение.
Так я могу назвать это так:
и это возвращает true или false в зависимости от того, someCollection содержит объект, для которого предикат возвращает true.
В любом случае, это всего лишь пример, и commons-collections устарели. Я просто забыл эквивалент в гуаве.
Java поддерживает закрытие просто отлично. Он просто не поддерживает функции, поэтому синтаксис, к которому вы привыкли для замыканий, гораздо более неудобный и громоздкий: вы должны обернуть все в классе с помощью метода. Например,
вернет Runnable объект, чей run() метод «закрывает» x передано, как и на любом языке, который поддерживает первоклассные функции и замыкания.
я использовал шаблон команды, который @jk. упомянуто, добавив тип возврата:
Я знаю, что это довольно старый пост, но у меня есть другое немного более простое решение. Вы можете создать другой класс внутри и сделать его абстрактным. Затем сделайте абстрактный метод, назовите его как угодно. В исходном классе создайте метод, который принимает новый класс в качестве параметра, в этом методе вызовите абстрактный метод. Это будет выглядеть примерно так.
теперь вы можете сделать что-то вроде этого, чтобы вызвать метод из класса.
Как я сказал Я знаю его старый, но так, я думаю, немного легче. Надеюсь, это поможет.
Java (пока) не поддерживает закрытие. Но есть и другие языки, такие как Scala и Groovy, которые работают в JVM и поддерживают закрытие.
Как передать функцию в качестве параметра в Java?
Можно ли передать метод в Java-метод в качестве параметра? Если да, может ли кто-нибудь, пожалуйста, направить меня? Это не кажется тривиальным
ОТВЕТЫ
Ответ 1
Java 8 и выше
Используя лямбда-выражения Java 8+, если у вас есть класс или интерфейс только с одним абстрактным методом (иногда называемым типом SAM), например:
затем в любом месте, где используется MyInterface, вы можете заменить лямбда-выражение:
Например, вы можете очень быстро создать новую тему:
И используйте синтаксис ссылки на метод, чтобы сделать его еще чище:
Без лямбда-выражений эти два последних примера выглядят так:
До Java 8
Этот образец известен как Образец Команды.
Имейте в виду, что вам лучше всего создать интерфейс для вашего конкретного использования. Если вы решили использовать callable, то вы заменили бы T выше на любой тип возвращаемого значения, например String.
В ответ на ваш комментарий ниже вы можете сказать:
затем назовите его, возможно, используя анонимный внутренний класс:
Имейте в виду, что это не «трюк». Это просто базовый концептуальный эквивалент java для функциональных указателей.
Ответ 2
Вы можете использовать отражение Java для этого. Этот метод будет представлен как экземпляр java.lang.reflect.Method.
Ответ 3
Лямбда-выражения
Синтаксис лямбда-выражений
Лямбда-выражение состоит из следующего:
Список формальных параметров, разделенных запятыми, заключенных в круглые скобки. Метод CheckPerson.test содержит один параметр, p, который представляет экземпляр класса Person.
Примечание: вы может опустить тип данных параметров в лямбда-выражении. В Кроме того, вы можете опустить круглые скобки, если есть только один параметр. Например, справедливо также следующее выражение лямбда:
Тело, состоящее из одного выражения или блока операторов. В этом примере используется следующее выражение:
Если вы укажете одно выражение, то среда выполнения Java оценит выражение и затем вернет его значение. С другой стороны, вы можете использовать оператор return:
Оператор return не является выражением; в выражении лямбда вы должны заключать выражения в фигурные скобки (<>). Однако у вас нет чтобы заключить вызов метода void в фигурные скобки. Например, следующее является действительным лямбда-выражением:
Обратите внимание, что лямбда-выражение очень похоже на объявление метода; вы можете рассматривать лямбда-выражения как анонимные методы-методы без имени.
Вот как вы можете «передать метод» с помощью выражения лямбда:
Ответ 4
Благодаря Java 8 вам не нужно выполнять следующие шаги, чтобы передать функцию методу, для чего предназначены лямбда, см. Oracle Lambda Expression учебник. Остальная часть этого сообщения описывает, что мы привыкли делать в плохие старые дни, чтобы реализовать эту функциональность.
Так, например, в коллекциях коллекций есть org.apache.commons.collections.CollectionUtils, который имеет множество статических методов, которые принимают объекты, переданные в, выбирать их случайным образом, там один называется с этой сигнатурой:
Требуется объект, реализующий интерфейс Predicate, что означает, что он должен иметь на нем метод, который принимает некоторый объект и возвращает логическое значение.
Поэтому я могу назвать это следующим образом:
и он возвращает true или false в зависимости от того, содержит ли someCollection объект, для которого предикат возвращает true.
Во всяком случае, это всего лишь пример, и коллективные фонды устарели. Я просто забываю эквивалент в Гуаве.
Ответ 5
Java поддерживает закрытие просто отлично. Он просто не поддерживает функции, поэтому синтаксис, который вы использовали для закрытия, намного более неудобен и громоздки: вы должны обернуть все в классе с помощью метода. Например,
Ответ 6
Я использовал шаблон команды @jk. упоминается, добавив тип возврата:
Ответ 7
Я знаю, что это довольно старый пост, но у меня есть другое, немного более простое решение. Вы можете создать другой класс внутри и сделать его абстрактным. Затем сделайте абстрактный метод, назовите его как хотите. В исходном классе создайте метод, который принимает новый класс в качестве параметра, в этом методе вызовите абстрактный метод. Это будет выглядеть примерно так.
Теперь вы можете сделать что-то подобное для вызова метода из класса.
Как я уже сказал, я знаю, что он старый, но так я думаю, что это немного проще. Надеюсь, поможет.
Ответ 8
Java не поддерживает (пока) поддержку закрытий. Но есть и другие языки, такие как Scala и Groovy, которые запускаются в JVM и поддерживают закрытие.