Рассмотреть возможность:
boolean somethingHappened = false;
Runnable doHappen = () -> { somethingHappened = true; }
Вы не можете этого сделать, потому что somethingHappened
не является окончательным. Смысл в том, что, как правило, вам не нужно изменять захваченные переменные из лямбда-области. Но, например, при использовании Stream.forEach
в этом нет необходимости.
Конечно, я мог бы написать обертку:
class Wrap<T>
{
public T value;
}
А затем я бы получил доступ к somethingHappened.value
и изменил это.
Мне просто интересно, существует ли уже такая оболочка в стандартной библиотеке Java. Я знаю только Optional
, который неизменен. Я мог бы злоупотреблять массивом final boolean[] mutableBool = { false }
, но это ужасно.
Плохо, я невнимательно прочитал.
Я не уверен, что это правильный способ сделать это, но классы в пакете java.util.concurrent.atomic работают.
Не в библиотеке Java. Но для этого в Apache Commons Lang есть Mutable. Он предлагает подклассы для каждой из примитивных оболочек, но каждая из них является изменчивой (например, MutableInt, MutableBoolean и т. д.).
Вы можете рассмотреть, будет ли использование этого возможно для вас.
ОБНОВИТЬ
AtomicBoolean - еще один вариант. Это позволяет вам делиться им между потоками и обновлять логическое значение, которое оно содержит.
Мои 0,02 доллара. Всякий раз, когда мне нужно обновить переменную из лямбды, я бы сделал шаг назад и еще раз подумал, действительно ли мне нужно это делать, и правильно ли использовать лямбда в этом случае. До сих пор (AFAIR) мне никогда не приходилось прибегать к какому-либо подходу для преодоления ограничения, согласно которому переменные, используемые в лямбда-выражении, должны быть эффективно окончательными.
Я принимаю этот ответ, поскольку в стандартной библиотеке его нет, и в вашем ответе, по крайней мере, упоминается очень распространенная библиотека, в которой есть класс для этого. Что касается вашего .02, я обратился к этому в своем вопросе.
Я согласен, что Runnable мог представить больше сценариев, где это необходимо, но все же я думаю, что есть и другие варианты. Один из вариантов, который сразу приходит на ум, — это AtomicBoolean.
Не создаст ли это ненужное впечатление, что происходит какая-то многопоточность? Я также беспокоился, что у него есть накладные расходы.
Да, это может быть не самое интуитивно понятное решение, когда нет многопоточности. А многопоточности уже нет? У меня сложилось такое впечатление, что вы использовали Runnable, и я предположил, что существует несколько потоков, и каждый поток должен знать значение somethingHappened
Нет, мой случай как раз делал someList.stream().forEach()
Да, то, что говорится в моем вопросе, я считаю немного ужасным. Но если я не получу ответа, я, вероятно, так и сделаю. Также, кстати, вы можете просто написать
boolean[] x = { false };
, здесь подразумевается новое.