Предполагая, что вы хотите сортировать по значению d['key']['subkey']
для каждого словаря d
в списке, используйте это:
sorted(yourdata, key=lambda d: d.get('key', {}).get('subkey'), reverse=True)
Как отмечено в комментариях, некоторые из них становятся неактуальными в Java 8, где final
может быть неявным. Только конечная переменная эффективно может использоваться в анонимном внутреннем классе или лямбда-выражении.
Это в основном из-за того, что Java управляет закрытием .
Когда вы создаете экземпляр анонимного внутреннего класса, любые переменные, которые используются в этом классе, имеют свои значения , скопированные через автогенерированный конструктор. Это позволяет компилятору автоматически генерировать различные дополнительные типы для хранения логического состояния «локальных переменных», как, например, компилятор C # ... (Когда C # захватывает переменную в анонимной функции, она действительно захватывает переменную - замыкание может обновить переменную таким образом, что это видно основной части метода, и наоборот.)
Поскольку значение было скопировано в экземпляр анонимного внутреннего класса, оно выглядело бы нечетным если переменная может быть изменена остальной частью метода - у вас может быть код, который, как представляется, работает с устаревшей переменной (потому что это эффективно то, что будет d работать с копией, сделанной в другое время). Аналогично, если вы можете вносить изменения внутри анонимного внутреннего класса, разработчики могут ожидать, что эти изменения будут видны внутри тела прилагаемого метода.
Создание окончательной переменной устраняет все эти возможности - поскольку значение не может вообще не измениться, вам не нужно беспокоиться о том, будут ли такие изменения видны. Единственные способы, позволяющие методу и анонимному внутреннему классу видеть изменения друг друга, - использовать изменяемый тип некоторого описания. Это может быть сам охватывающий класс, массив, изменяемый тип оболочки ... что-то в этом роде. В принципе, это немного похоже на связь между одним и тем же способом: изменения, внесенные в параметры одного метода, не видны его вызывающей стороне, но изменения, внесенные в объекты , относящиеся к по параметрам.
Если вам интересно более подробное сравнение между закрытием Java и C #, у меня есть статья , которая идет дальше. Я хотел сосредоточиться на стороне Java в этом ответе:)
Вы можете создать переменную уровня класса для получения возвращаемого значения.
class A {
int k = 0;
private void f(Button b, int a){
b.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
k = a * 5;
}
});
}
теперь вы можете получить значение K и использовать его там, где хотите. экземпляр привязан к основному классу и может получить доступ к конечным локальным переменным его содержащего метода. Когда экземпляр использует конечный локальный из его содержащего метода, переменная сохраняет значение, которое оно удерживало во время создания экземпляра, даже если переменная вышла за пределы области (это, по сути, грубая ограниченная версия закрытия Java).
Поскольку локальный внутренний класс не является членом класса или пакета, он не объявляется с уровнем доступа. (Однако ясно, что его собственные члены имеют уровни доступа, как в обычном классе.)
List.forEach
безопасен.
– RuntimeException
30 October 2015 в 12:54
AtomicReference
или AtomicInt
для этой же цели ...
– csharpfolk
6 August 2017 в 12:35
private void f(Button b, final int a[]) {
b.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
a[0] = a[0] * 5;
}
});
}
Анонимный класс является внутренним классом , и строгое правило применяется к внутренним классам (JLS 8.1.3) :
Любая локальная переменная, параметр формального метода или параметр обработчика исключений, используемые, но не объявленные во внутреннем классе, должны быть объявлены окончательными. Любая локальная переменная, используемая, но не объявленная во внутреннем классе, должна быть явно назначена перед телом внутреннего класса.
blockquote>Я не нашел причины или объяснения по jls или jvms но мы знаем, что компилятор создает отдельный файл класса для каждого внутреннего класса, и он должен убедиться, что методы, объявленные в этом файле класса (на уровне байтового кода), по крайней мере имеют доступ к значениям локальных переменных .
( У Джона есть полный ответ - я сохраняю его одним, потому что его может заинтересовать правило JLS)
Попробуйте этот код,
Создайте список массивов и поместите значение внутри него и верните его:
private ArrayList f(Button b, final int a)
{
final ArrayList al = new ArrayList();
b.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
int b = a*5;
al.add(b);
}
});
return al;
}
Поскольку Jon имеет детали реализации, ответ на другой возможный ответ будет состоять в том, что JVM не хочет обрабатывать запись в записи, которая завершила его активацию.
Рассмотрим Если ваш lambdas вместо того, чтобы быть примененным, хранится в некотором месте и запускается позже.
Я помню, что в Smalltalk вы получите незаконный магазин, созданный, когда вы сделаете такую модификацию.
Когда внутри тела метода определен анонимный внутренний класс, все переменные, объявленные окончательными в объеме этого метода, доступны из внутреннего класса. Для скалярных значений после его назначения значение конечной переменной не может измениться. Для значений объекта ссылка не может быть изменена. Это позволяет компилятору Java «захватить» значение переменной во время выполнения и хранить копию как поле во внутреннем классе. Когда внешний метод завершен и его стек стека удален, исходная переменная исчезла, но частная копия внутреннего класса сохраняется в собственной памяти класса.
Методы внутри монономического внутреннего класса могут быть вызваны после того, как поток, который породил его, завершился. В вашем примере внутренний класс будет вызываться в потоке отправки событий, а не в том же потоке, что и его созданный. Следовательно, объем переменных будет различным. Поэтому, чтобы защитить такие проблемы с областью выделения переменных, вы должны объявить их окончательными.
Причина, по которой доступ ограничивается только локальными конечными переменными, заключается в том, что если все локальные переменные станут доступными, они сначала должны быть скопированы в отдельный раздел, где внутренние классы могут иметь к ним доступ и поддерживать несколько копий изменяемых локальных переменных могут приводить к несогласованным данным. В то время как конечные переменные неизменяемы и, следовательно, любое количество копий для них не окажет никакого влияния на согласованность данных.
Int
переназначается внутри замыкания, измените эту переменную на экземпляр IntRef
(по существу, изменяемый Integer
обертка). Каждый переменный доступ затем переписывается соответствующим образом.
– Adowrath
15 September 2017 в 07:30
Возможно, этот трюк дает идею
Boolean var= new anonymousClass(){
private String myVar; //String for example
@Overriden public Boolean method(int i){
//use myVar and i
}
public String setVar(String var){myVar=var; return this;} //Returns self instane
}.setVar("Hello").method(3);
Ну, в Java переменная может быть окончательной не только как параметр, но как поле уровня класса, например
public class Test
{
public final int a = 3;
или как локальная переменная, например
public static void main(String[] args)
{
final int a = 3;
Если вы хотите получить доступ и изменить переменную из анонимного класса, вам может потребоваться сделать переменную переменной уровня класса в классе-оболочке.
public class Test
{
public int a;
public void doSomething()
{
Runnable runnable =
new Runnable()
{
public void run()
{
System.out.println(a);
a = a+1;
}
};
}
}
Вы не можете имеют переменную как окончательную и дают ей новое значение. final
означает именно это: значение неизменное и окончательное.
И поскольку он окончательный, Java может безопасно скопировать его в локальные анонимные классы. Вы не получаете ссылку в int (тем более, что вы не можете иметь ссылки на примитивы, такие как int в Java, просто ссылки на объекты).
Он просто копирует значение a в неявное int, называемое a в вашем анонимном классе.
static
. Может быть, более понятно, если вы используете «переменную экземпляра». вместо.
– eljenso
19 January 2011 в 13:23
final
(но он все равно должен быть окончательным). – Thilo 4 March 2016 в 08:56