Zielony Smok - logo witryny

Runnable

Interfejs zawiera metodę void run() . W klasie implementującej ten interfejs musimy zaimplementować metodę run(), najczęściej tworząc klasę anonimową:

Zamiast kodu:

SwingUtilities.invokeLater(new Runnable(){
	@Override
	public void run() {
		new Test(new ButtonPanel());
	}
});

możemy zastosować kod:

SwingUtilities.invokeLater(() -> new Test(new ButtonPanel()));

Metoda invokeLater() oczekuje obiektu klasy implementującej Runnable , w związku z czym kompilator wie, że puste nawiasy () odnoszą się do metody run() interfejsu Runnable.

Wyrażenie lambda zawiera puste nawiasy () ponieważ metoda run() również nie przyjmuje żadnych argumentów.

Metoda run nie zwraca żadnego typu, ale wywołuje konstruktor klasy Test , który wywołuje konstruktor klasy ButtonPanel.

Wyrażenie lambda nie zwraca nic ponieważ metoda run() nie zwraca nic.

ActionListener

Metoda addActionListener() wymaga jako argumentu obiektu klasy implementującej interfejs ActionListener . Implementacja tej klasy musi konkretyzować metodę void actionPerformed(ActionEvent e) , przyjmującą jako argument obiekt klasy ActionEvent.

Normalnie tworzymy klasę anonimową:

    button.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
    button.setText("Kliknij jeszcze raz!");
    }
    });
    

Obecnie możemy użyć wyrażenia lambda:

button.addActionListener(event -> button.setText("Kliknij jeszcze raz"));

Kompilator wie, że musi powstać obiekt klasy implementującej interfejs ActionListener , a więc wiadomo, że należy użyć metody actionPerformed , co oznacza, że jedyny argument event jest obiektem klasy ActionEvent.

Wyrażenie lambda nie zwraca żadnego typu, bo metoda actionPerformed nic nie zwraca, ale wywołana zostaje metoda setText() obiektu button.

PropertyChangeListener

Czasami implementowana metoda interfejsu wymaga większej ilości kodu niż jedna linijka. jak wtedy wygląda wyrażenie lambda?

Interfejs PropertyChangeListener pozwala na śledzenie zmian wartości pól w obiektach.

smok.addPropertyChangeListener(new PropertyChangeListener(){
	@Override
	public void propertyChange(PropertyChangeEvent evt) {
		Integer newValue = (Integer)evt.getNewValue();
		System.out.println(newValue);
	}
});

Zamiennie możemy użyć wyrażenia lambda:

smok.addPropertyChangeListener(evt -> {
	Integer newValue = (Integer)evt.getNewValue();
	System.out.println(newValue);
});

VetoableChangeListener

smok.addVetoableChangeListener(new VetoableChangeListener(){
	@Override
	public void vetoableChange(PropertyChangeEvent evt)
			throws PropertyVetoException {
		Integer newVal = (Integer)evt.getNewValue();
		int val = newVal.intValue();
		if(val < min){
			throw new PropertyVetoException(
					"Stop. Smok zaraz umrze z głodu", evt);
		}
		if(val > max){
			throw new PropertyVetoException(
					"Stop. Smok zaraz pęknie z przejedzenia", evt);
		}
	}
});

I to samo z użyciem wyrażenia lambda:

smok.addVetoableChangeListener(evt -> {
	Integer newVal = (Integer)evt.getNewValue();
	int val = newVal.intValue();
	if(val < min){
		throw new PropertyVetoException(
				"Stop. Smok zaraz umrze z głodu", evt);
	}
	if(val > max){
		throw new PropertyVetoException(
				"Stop. Smok zaraz pęknie z przejedzenia", evt);
	}
});

Comparator

    Comparator<Smoklon> comp1 = new Comparator<>(){
    @Override
    public int compare(Smoklon o1, Smoklon o2) {
    return (o1.getDywizja()).compareTo(o2.getDywizja());
    }
    };
    Collections.sort(list, comp1);
    

Możemy też użyć wyrażenia lambda:

Comparator<Smoklon> comp2 = (o1, o2) -> (o1.getDywizja()).compareTo(o2.getDywizja());
Collections.sort(list, comp2);

Możemy również podstawić wyrażenie lambda bezpośrednio do metody sort().

Collections.sort(list, (o1, o2) -> (o1.getDywizja()).compareTo(o2.getDywizja()));