Полезно ли лениться


О пользе лени: 5 причин разрешить себе бездельничать :: Здоровье :: РБК Стиль

© Lenin Estrada/Unsplash

Автор Ульяна Смирнова

31 октября 2019

Ничего не делать — это одна из самых полезных вещей, которые мы можем для себя сделать. Ученые доказали: лень укрепляет здоровье и делает нас более продуктивными. Вот пять неоспоримых аргументов на этот счет.

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

Причина № 1. Повышает творческие способности

Многие до сих пор считают лень плохим качеством, которое мешает двигаться вперед и достигать поставленных целей. Но известные авторы и художники неспроста регулярно находят в своем графике время для длительных пеших прогулок. Они хорошо знакомы с так называемым «эффектом инкубации»: когда вы перестаете концентрироваться на решаемой задаче и позволяете себе расслабиться, подсознание находит лучшее решение без вашей помощи.

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

Причина № 2. Делает нас более продуктивными

Еще недавно в книгах и статьях по психологии часто писали о том, как победить лень, заставить себя работать и много успевать. Теперь на полках магазинов появляется все больше книг о полезной и продуктивной лени. «Нужно постоянно двигаться вперед», «нельзя сидеть на месте», «важно развиваться во всех сферах» — из-за таких установок жизнь становится похожа на бег белки в колесе, а организм все чаще дает сбой и отказывается работать.

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

Причина № 3. Защищает мозг от перегрузок

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

Ученые из Университета Британской Колумбии считают, что наш мозг генетически предрасположен к лени: экономия энергии была необходима для выживания людей. Когда мы ленимся, мозг перезагружается и укрепляет свои нейронные связи. Неслучайно многие великие открытия были совершены в моменты безделья. Как известно, Архимед открыл закон гидростатики прямо в ванне, а Ньютон догадался о силе притяжения, когда отдыхал под яблоней.

Для участия в эксперименте американские ученые пригласили 12 женщин и 12 мужчин, которых разделили на две группы. Одним дали простой компьютерный джойстик, вторым — с неполадками (например, когда они двигали его вправо, курсор перемещался вниз). Исследователи изучили мозговую активность в периоды отдыха и работы над заданиями. Оказалось, что во время перерывов мозг участников второй группы не отдыхал, а обрабатывал и фиксировал новое.

Причина № 4. Улучшает концентрацию внимания

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

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

Причина № 5. Укрепляет здоровье и продлевает жизнь

© Artem Beliaikin/Unsplash

Лень — это заложенный природой механизм, который продлевает нашу жизнь. Ученые из Канзасского университета провели необычное исследование. Наблюдая за моллюсками в Атлантическом океане, они выяснили, что те кальмары, каракатицы и осьминоги, которые расходовали свою энергию больше остальных, умирали (или вымирали) значительно быстрее. При этом более медлительные особи оказались лучше приспособлены к выживанию.

Поскольку человеческое сердце напоминает мотор, то чем мягче и спокойнее оно работает, тем крепче будет здоровье. Работа в режиме нон-стоп повышает кровяное давление, ослабляет иммунитет и активизирует выработку кортизола — гормона стресса. Он негативно влияет не только на наше самочувствие, но и на красоту. Если же расход энергии падает, нейроны мозга производят гормоны радости и счастья. Другими словами, мы «запрограммированы» лениться.

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

.net - Что такое ленивая инициализация и чем она полезна?

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
.

17 Здоровые и практичные стратегии

Нужен ленивый день? Это случается с лучшими из нас. В это напряженное время не просто устраивать ленивый день, а очень нужно.

Но если вы обнаружите, что чаще проводите ленивые дни, чем нет, и у вас возникают проблемы с выполнением дел, это может быть признаком того, что что-то происходит.

Отсутствие энтузиазма к своей работе, непреодолимый список дел и даже основное заболевание - это лишь некоторые из вещей, которые могут помешать вашему желанию добиваться результатов.

Здесь мы рассмотрим все основы и расскажем, как перестать лень, чтобы вы могли работать более продуктивно.

«Как мне перестать лень?» Ответ может быть не таким резким, как вы ожидали. Хотя некоторые люди могут быть более ленивыми, чем другие, даже очень продуктивным людям иногда бывает сложно добиться цели.

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

1. Сделайте свои цели управляемыми

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

Избегайте перегрузки, ставя более мелкие, достижимые цели, которые приведут вас туда, где вы хотите быть, не перегружая вас на этом пути.

2. Не ожидайте, что вы будете совершенны.

Перфекционизм растет, и это наносит психологический урон.

Одно исследование 2017 года, в котором изучались студенты колледжей в период с 1989 по 2016 год, показало, что с годами перфекционизм растет.Исследователи отметили, что «молодые люди [теперь] сталкиваются с более конкурентной средой, более нереалистичными ожиданиями и более тревожными и контролирующими родителями, чем предыдущие поколения».

Этот рост перфекционизма заставляет людей чрезмерно критически относиться к себе и другим. Это также привело к усилению депрессии и беспокойства.

Другое небольшое исследование студентов колледжей пришло к выводу, что ожидание совершенства связано с избеганием совладания, что заставляет вас избегать контакта со стрессорами.

3. Используйте позитивный вместо негативного разговора с самим собой

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

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

4. Составьте план действий

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

5. Используйте свои сильные стороны

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

6. Признавайте свои достижения в процессе

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

7. Обращение за помощью

Многие люди считают, что обращение за помощью - признак слабости. Но если не попросить о помощи, это может обернуться для вас неудачей.Исследование 2018 года показало, что люди, которые не обращаются за помощью к коллегам, с большей вероятностью будут недовольны своей работой и имеют более низкий уровень производительности. Их работодатели также воспринимали их менее благосклонно.

Обращение за помощью увеличивает ваши шансы на успех и помогает вам общаться с другими людьми, которые могут воодушевить и мотивировать вас.

8. Не отвлекайтесь

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

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

9. Делайте утомительные дела веселыми

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

10. Вознаграждайте себя

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

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

1. Ешьте продукты с высоким содержанием белка

Вы задаетесь вопросом, «как мне перестать лениться?» Некоторые продукты повышают вашу энергию и поддерживают стабильный уровень сахара в крови, поэтому вы с меньшей вероятностью будете чувствовать себя вялым и ленивым.Это делают продукты с высоким содержанием белка, например:

  • Греческий йогурт
  • миндаль
  • яйца
  • тунец

2. Избегайте сладких и жирных продуктов

Питание и продуктивность взаимосвязаны. Избегайте продуктов, которые истощают вашу энергию, потому что они медленно перевариваются или вызывают скачки сахара в крови. К ним относятся:

3. Упражнение

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

4. Сон и отдых

Есть много вещей, которые вы можете сделать, чтобы лучше спать по ночам - от того, чтобы не проводить время перед сном перед сном, до ограничения времени на сон в течение дня.

Старайтесь спать по семь-девять часов каждую ночь, чтобы чувствовать себя отдохнувшим и готовым к предстоящему дню.

5. Управляйте стрессом

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

6. Носите воду с собой.

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

7. Бросить курить

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

Бросить курить может быть сложно, но ваш врач может помочь вам составить индивидуальный план действий.

Иногда это не лень, а симптом основного заболевания, которое может мешать вам делать то, что вы должны.Если вы обнаружите, что потеряли интерес к занятиям, которые обычно приносили бы удовольствие, и у вас нет энергии или сосредоточенности, чтобы сделать что-то, поговорите с врачом.

Психические расстройства

Многие психические расстройства могут вызывать симптомы, которые вы можете принять за лень, например отсутствие мотивации, хроническую усталость и социальную изоляцию. К таким состояниям относятся:

Медицинские условия

Медицинские условия могут вызвать изменения в вашем энергетическом уровне и помешать вам нормально функционировать.Примеры:

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

Если у вас возникают проблемы с поиском энергии и желания делать что-то чаще, поговорите с врачом, чтобы определить, может ли быть причиной основное заболевание.

.

ленивых вычислений на Java с ленивым типом

Я выбрал ленивого человека для тяжелой работы.
Потому что ленивый найдет легкий способ сделать это.
- Билл Гейтс

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

Ленивое вычисление экономит вычислительные ресурсы, избегая ненужных вычислений. Лень позволяет манипулировать данными, которые невозможно использовать в вычислениях, такими как бесконечные списки или конечные данные, которые могут переполнять доступную память, например огромные файлы. Затем важно иметь возможность использовать ленивое вычисление даже в языках, которые являются строгими по своей природе, такими как Java. На таких языках нам нужно научиться реализовывать ленивые типы, чем мы и займемся в этой статье.

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

Абстрагирование вычислительных контекстов

Лень - это не только шаблон для экономии ресурсов. Это вычислительный контекст, который можно применить к любому выражению. В этом смысле не следует противопоставлять строгость (тот факт, что оценка выполняется сразу после определения выражения). Следует противопоставлять выражения вне контекста. Выражения могут использоваться вне контекста или в контексте. Конечно, можно возразить, что все выражения определены в контексте программы.Итак, допустим, что некоторые выражения могут быть определены на дополнительном уровне контекста. А поскольку все выражения определены в контексте программы (насколько нам известно), мы забудем об этом «верхнем» контексте и рассмотрим только дополнительный контекстный слой.

Лень - это особый контекст. Когда выражение помещается в этот контекст, это просто означает, что оно, возможно, еще не вычислено. Более того, помещение его в этот контекст предотвращает оценку до тех пор, пока она нам не понадобится.Обратите внимание, что мы могли бы, однако, поместить в контекст лени выражение, которое уже вычислено. Это, конечно, ничего не изменит в отношении оценки, но может быть полезно комбинировать выражения, как мы скоро увидим.

Есть много других возможных вычислительных контекстов. Мы могли манипулировать выражениями, на вычисление которых уходит много времени. Эти выражения могут быть помещены в другой контекст, в котором оценка начнется немедленно, но позволит нам манипулировать ими до завершения оценки.Или мы могли бы поместить выражения в конкретный контекст, что позволит нам прозрачно справляться с ошибками. В таком контексте выражение будет оцениваться либо по его результату, либо по ошибке. Но как насчет оценки, которая займет много времени и может привести к ошибке? Что ж, мы могли бы определить для этого конкретный контекст, но мы могли бы лучше скомпоновать два первых контекста. Составление контекстов разных типов - интересная проблема. Но на данный момент мы рассмотрим только создание нескольких экземпляров одного и того же контекста, что означает создание лени.Но прежде чем смотреть на это, мы должны сначала реализовать типа лени .

Простой подход к типу лени

Программисты всегда знали, как реализовать минимальную лень там, где им это нужно. Самый простой способ реализовать ленивое свойство, вероятно, следующий:

  личное сообщение String; public String getMessage () { if (message == null) { сообщение = constructMessage (); } ответное сообщение; }  

В этом примере свойство message лениво вычисляется при первом вызове его геттера.Метод constructMessage вызывается «лениво», но это происходит не из-за самого вызова метода, а потому, что это происходит в условной структуре if , которая является ленивой. К сожалению, мы не можем использовать эту технику для аргументов метода, потому что как только мы будем использовать свойство message в качестве аргумента метода, оно будет вычислено, даже если мы не будем использовать значение:

  общедоступное строковое сообщение; public String getMessage () { if (message == null) { сообщение = constructMessage (); } ответное сообщение; } private String constructMessage () { Система.out.println («Оценочное сообщение»); return "Сообщение"; } public void doNothingWith (String string) { } public void testLaziness () { doNothingWith (getMessage ()); }  

В этом примере на консоли будет выведено сообщение Evaluating , хотя мы никогда не используем полученное значение. Можем ли мы сделать лучше?

Использование существующего типа

Да, можем. Мы всегда могли, но теперь это намного проще, когда у нас есть лямбда-выражения и ссылки на методы. До Java 8 мы могли написать:

  public void doNothingWith (строка поставщика ) { } public void testLaziness () { doNothingWith ((новый поставщик  () { @Override public String get () { return getMessage (); } })); }  

Конечно, поскольку интерфейса Supplier не существовало, нам пришлось бы создать его, что довольно просто:

  общедоступный интерфейс Поставщик  { T получить (); }  

С Java 8 мы можем использовать стандартный java.util.function.Supplier interface и лямбда:

  public void testLaziness () { doNothingWith (() -> getMessage ()); }  

Или лучше, мы можем заменить лямбду ссылкой на метод:

  public void testLaziness () { doNothingWith (this :: getMessage); }  

Обратите внимание, что эти примеры не эквивалентны. Использование анонимного класса приведет к созданию экземпляра этого класса. Напротив, использование лямбда не приведет к созданию объекта, а только метода.А если используется ссылка на метод, никакой метод даже не будет создан, поскольку указанный метод будет просто вызван. Это имеет некоторое значение с точки зрения эффективности, но не только. Основное последствие, с точки зрения программиста, заключается в том, что ссылки и будут ссылаться на анонимный класс в первом случае и на включающий класс в случае лямбда-выражения или ссылки на метод.

Создание отложенных типов

Лень, которую мы получаем, используя Supplier , полезна, но мы можем сделать ее намного более мощной.Представьте, что у нас есть две ленивые строки, которые мы хотим объединить:

  закрытый String constructMessage ( Поставщик  приветствует, имя поставщика ) { вернуть greetings.get () + name.get (); }  

Какая польза от лени, если мы вынуждены оценивать выражения для их составления? Если мы точно знаем, что нам понадобится результат композиции, имеет смысл оценить выражения перед их составлением. Но мы могли бы захотеть составить два ленивых выражения и получить ленивый результат.Это означает, что мы хотели бы составлять значения в контексте, не вынимая их из контекста. Для этого нам просто нужно обернуть композицию в новый экземпляр контекста lazy , что означает Supplier :

  частный поставщик  constructMessage ( Поставщик  приветствует, имя поставщика ) { return () -> greetings.get () + name.get (); }  

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

Разработка продвинутого ленивого типа

Это хорошее начало, поскольку оно уже более действенно, чем простая лень, но мы можем добиться большего.Интерфейс Supplier может только отложить оценку до тех пор, пока мы не вызовем метод get . Само по себе это не позволяет создавать ленивые значения. А что, если метод get выдаст исключение? А что, если мы хотим применить функцию к этому отложенному значению, не вызывая вычисления? Мы можем решить все эти проблемы извне, но поскольку Java - объектно-ориентированный язык, мы должны делегировать эту работу самому ленивому типу. Мы можем начать с создания собственного интерфейса:

  @ Функциональный интерфейс открытый интерфейс Lazy  { Получить (); }  

Мы могли бы захотеть использовать наш интерфейс там, где ожидается Supplier .Чтобы это стало возможным, все, что нам нужно сделать, это расширить Supplier :

  @ Функциональный интерфейс открытый интерфейс Lazy  расширяет Supplier  {}  

Ленивое применение функций

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

  по умолчанию  Lazy  map (Function  f) { return () -> f.применить (получить ()); }  

Возможно, нам придется иметь дело с возможностью исключения в методе get . У нас есть несколько возможностей:

  • Повторно вызвать исключение. У нас мало что для этого делать, так как это произойдет автоматически, если мы ничего не сделаем. Однако следует отметить, что исключение может быть только RuntimeException , поскольку методы в функциональных интерфейсах JDK не могут генерировать проверенные исключения. Таким образом, если оценка вызывает проверенное исключение, мы должны либо обработать его на месте, либо заключить в непроверенное исключение перед повторной генерацией.Однако создание исключений - это то, чего мы хотим избежать в функциональном программировании.

  • Возвращает специальный тип, указывающий, что произошла ошибка. Это может быть Optional . Главный недостаток в том, что Optional не может содержать исключение. Он только указывает на то, что значение могло присутствовать, хотя это не так, но не может сказать почему. В следующей статье мы увидим, как решить эту проблему.

  • Вернуть значение по умолчанию.Конечно, мы не знаем, какое значение вернуть, поэтому оно должно быть предоставлено вызывающим.

Реализовать случай, возвращающий значение по умолчанию, просто:

  default  Lazy  map (Function  f, B defaultValue) { return () -> { пытаться { вернуть f.apply (get ()); } catch (Exception e) { вернуть defaultValue; } }; }  

Это можно использовать, как в следующем примере:

  статический Ленивый  name1 = () -> { Система.out.println ("Оценка name1"); вернуть «Боб»; }; static Lazy  name2 = () -> { System.out.println ("Оценка name2"); выбросить новое исключение RuntimeException (); }; статическая функция  constructMessage = имя -> String.format ("Привет,% s!", имя); public static void main (String ... args) { String defaultValue = "Извините, но я не разговариваю с анонимными людьми."; System.out.println (name1.map (constructMessage, defaultValue) .get ()); System.out.println ("----"); Система.out.println (name2.map (constructMessage, defaultValue) .get ()); }  

И вот результат, отображаемый на консоли:

  Оценка name1 Привет, Боб! ---- Оценка name2 Извините, но я не разговариваю с анонимами.  

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

  default  Lazy  map (Function  f, Lazy  defaultValue) { return () -> { пытаться { возврат f.применить (получить ()); } catch (Exception e) { вернуть defaultValue.get (); } }; }  

Возврат Дополнительный немного сложнее. Вот возможная реализация:

  по умолчанию  Ленивый <Необязательно > mapOption (Функция  f) { return () -> { пытаться { return Optional.of (f.apply (get ())); } catch (Exception e) { return Optional.empty (); } }; }  

Это даст тот же результат, если мы немного изменим наш пример программы:

  public static void main (String... args) { String defaultValue = "Извините, но я не разговариваю с анонимными людьми."; System.out.println (имя1 .mapOption (constructMessage) .получить() .orElse (defaultValue)); System.out.println ("----"); System.out.println (имя2 .mapOption (constructMessage) .получить() .orElse (defaultValue)); }  

Отображение функции, возвращающей ленивый тип

Иногда вместо Function нам нужно отобразить функцию с результатом Lazy .Если мы передадим такую ​​функцию методу map , результатом будет Lazy > . Какова бы ни была польза от Lazy , быть ленивым - это уже слишком, поэтому нам нужен способ превратить Lazy > в Lazy . Это также очень распространенный вариант использования, который обычно называется сглаживание или соединение . Вот как это можно реализовать:

  static  Lazy  flatten (Lazy > lla) { вернуть lla.получить(); }  

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

  по умолчанию  Lazy  flatMap (Function > f) { return () -> f.apply (получить ()). получить (); }  

С помощью такой функции мы можем составить столько ленивых значений, сколько нам нужно, ничего не оценивая:

  static Lazy  lazyGreetings = () -> { Система.out.println («Оценивающее приветствие»); return «Привет»; }; static Lazy  lazyFirstName = () -> { System.out.println ("Оценка имени"); вернуть «Джейн»; }; static Lazy  lazyLastName = () -> { System.out.println ("Оценка фамилии"); вернуть "Лань"; }; public static void main (String ... args) { Ленивое сообщение  = lazyGreetings .flatMap (привет -> lazyFirstName .flatMap (firstName -> lazyLastName .карта (lastName -> String.format ( "% s,% s% s!", привет, firstName, lastName)))); System.out.println («Сообщение составлено, но еще ничего не оценено»); System.out.print (message.get ()); }  

Результат:

  Сообщение составлено, но еще ничего не проверено Оценка приветствия Оценка имени Оценка фамилии Привет, Джейн Доу!  

Это показывает, что ничего не оценивается до вызова метода get для результата.

Ввод значения в контекст

Как я уже сказал, иногда нам нужно поместить уже вычисленное выражение в ленивый контекст. Это ничего не меняет в отношении оценки, но необходимо для составления оцененных выражений с невычисленными. Это делается статическим методом, который обычно называется return или unit . Java использует для этого другое соглашение, вызывая этот метод из , поэтому мы определим такой метод в нашем интерфейсе:

  static  Ленивый  из (A a) { return () -> а; }  

Поведение абстрагирования

Реализованный нами тип Lazy во многом аналогичен поведению многих других типов, например Optional , CompletableFuture , Stream или функционального односвязного списка функциональных языков (но не java.Утилит. список ). Наличие метода flatMap , а также способа создания Lazy из экземпляра A делает наш ленивый тип Lazy монадой (при условии, что эти методы удовлетворяют некоторым дополнительным условиям). И все монады могут быть составлены из монад одного типа и с функциями, точно так же, как мы это сделали здесь.

Использование монад позволяет абстрагироваться от конкретного поведения (здесь, лени) от того, как это поведение может быть скомпоновано с другими элементами, путем предоставления контекста, в котором могут происходить обычные вычисления, хотя эти обычные вычисления обычно не применяются.Это то, что мы видели, когда применили Function к ленивому A , не преобразовав этот ленивый A в оцененный.

Некоторые другие монады могут показаться очень похожими на нашу монаду Lazy . Например, Future (не Java Future , а нечто большее, чем CompletableFuture ) также представляет неоцененные данные. Большая разница с Lazy заключается в том, что Lazy предназначен для задержки оценки (и, возможно, ее предотвращения), в то время как Future в основном предназначен для быстрого запуска оценки, результат которой будет доступен только позже.Помимо этого, все другие характеристики, такие как способ их компоновки с использованием карты map и flatMap , эквивалентны, хотя этим методам даны разные имена.

Лучшее средство для обработки эффектов

В нашем примере мы вызывали метод get , чтобы начать оценку, когда мы хотели иметь возможность вывести результат на консоль. Другими словами, мы извлекли значение из его контекста, чтобы применить к нему эффект.Это отменяет эффект лени. Конечно, иногда в этом может возникнуть необходимость, но мы должны стараться как можно дольше откладывать это. Функциональные программисты-фундаменталисты используют для этого очень сложные методы, но для начала мы можем использовать и гораздо более простые.

Реализованное выше преобразование состоит из введения необработанной функции в контексте лени, а не извлечения значения для передачи его функции. То же самое можно сделать и с эффектами. Вместо вызова get для вывода оцененного результата на консоль мы можем передать эффект печати на консоль в контекст Lazy .Для этого мы будем использовать метод, который мы будем называть для каждого , хотя в контексте есть только одно значение. Это позволяет нам абстрагироваться от принципа, который одинаков для большинства контекстов, под одним названием.

Реализация очень проста:

  по умолчанию недействительно для каждого (Потребитель  c) { c.accept (получить ()); }  

Используя этот метод, наш последний пример можно переписать как:

  public static void main (String ... args) { Ленивое сообщение  = lazyGreetings .flatMap (привет -> lazyFirstName .flatMap (firstName -> lazyLastName .map (lastName -> String.format ( "% s,% s% s!", привет, firstName, lastName)))); System.out.println («Сообщение составлено, но еще ничего не оценено»); message.forEach (System.out :: println); }  

Обратите внимание, что наш метод forEach принимает значение Consumer , которое применяется к для каждого значения в контексте. Тот факт, что для Lazy это не может быть ничего, кроме одного значения, не имеет значения.Важно четко видеть, что это точно такая же концепция, как forEach в Java 8 Stream . Это (среди прочего) то, что Optional делает неправильно: вызов этого метода ifPresent вводит пользователя в заблуждение, заставляя его поверить в то, что он отличается от метода forEach из Stream , когда у них много общего. важнее того, что их отличает.

Воспоминание о результатах оценки

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

Но интерфейс не может хранить значение, поэтому мы должны выбрать другой дизайн. Вместо создания интерфейса, расширяющего Supplier , мы можем создать класс, содержащий Supplier . Этот класс будет хранить как Supplier , так и A , используя тот же метод, который мы использовали в первом примере:

  публичный класс Lazy  { частный конечный поставщик  sValue; частное значение A; private Lazy (значение поставщика ) { этот.sValue = значение; } public A get () { if (value == null) { значение = sValue.get (); } возвращаемое значение; } public  Lazy  map (Function  f) { return new Lazy <> (() -> f.apply (this.get ())); } public  Lazy  map (Function  f, B defaultValue) { return new Lazy <> (() -> { пытаться { return f.apply (this.get ()); } catch (Exception e) { вернуть defaultValue; } }); } public  Lazy > mapOption (Function  f) { return new Lazy <> (() -> { пытаться { return Необязательно.из (f.apply (this.get ())); } catch (Exception e) { return Optional.empty (); } }); } public  Lazy  flatMap (Function > f) { вернуть новый Lazy <> (() -> f.apply (get ()). get ()); } public void forEach (Consumer  c) { c.accept (получить ()); } public static  Lazy  of (Supplier  a) { вернуть новый Lazy <> (a); } public static  Lazy  of (A a) { return new Lazy <> (() -> a); } }  

Обратите внимание на наличие двух статических фабричных методов, позволяющих создать Lazy из Supplier или из уже оцененного A .Выполнение следующего теста показывает преимущества мемоизации:

  static Lazy  name1 = Lazy.of (() -> { System.out.println ("Оценка name1"); вернуть «Боб»; }); static Lazy  name2 = Lazy.of (() -> { System.out.println ("Оценка name2"); выбросить новое исключение RuntimeException (); }); статическая функция  constructMessage = имя -> String.format ("Привет,% s!", имя); public static void main (String ... args) { String defaultValue = "Извините, но я не разговариваю с анонимными людьми."; name1.map (constructMessage, defaultValue) .forEach (System.out :: println); System.out.println ("----"); name2.map (constructMessage, defaultValue) .forEach (System.out :: println); System.out.println ("----"); name1.mapOption (constructMessage) .forEach (System.out :: println); System.out.println ("----"); name2.mapOption (constructMessage) .forEach (System.out :: println); }  

Результат показывает, что успешная оценка происходит только один раз:

  Оценка name1 Привет, Боб! ---- Оценка name2 Извините, но я не разговариваю с анонимами.---- Необязательно [Привет, Боб!] ---- Оценка name2 Необязательно. Пустой  

Здесь результат неудачной оценки не запоминается. Это дает нам возможность повторить попытку при следующем вызове, который может оказаться полезным, а может и не оказаться полезным, в зависимости от причины сбоя. Если мы хотим, чтобы сбой запомнился, мы можем просто сохранить Optional как результат вызова.

Сводка

Мы узнали, как эффективно реализовать ленивость типов:

  • Использование поставщика для обозначения лени
  • Составление ленивых типов для получения ленивого результата
  • Отображение функции, возвращающей вычисленное значение, в ленивый тип
  • Отображение функции, возвращающей ленивое значение, в ленивый тип
  • Применение эффекта к ленивым типам
  • Запоминание ленивых типов

Изучая эти методы, мы обнаружили, насколько лень является вычислительным контекстом .Мы научились

  • Поместите выражение в контекст
  • Объединить значения в контексте
  • Применить эффект к значениям в контексте

Различение между различными типами контекстов и абстрагирование этих типов контекстов в элементы, которые могут быть объединены на более высоком уровне вычислений, является основной частью функционального программирования.

.

c # - когда мне следует использовать ленивую загрузку и насколько ленивой она должна быть

Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии
.

Смотрите также