Instructor: James Riely
public class Swing1 extends Frame {
public static void main (String[] args) { new Swing1 (); }
int count = 0;
public Swing1 () {
setSize (200, 100); setLayout (new FlowLayout ());
Button button = new Button ("Go"); add (button);
Label out = new Label ("000", Label.CENTER); add (out);
button.addActionListener (new MyActionListener(this, out));
setVisible (true);
}
}
class MyActionListener implements ActionListener {
private Swing1 parent;
private Label out;
public MyActionListener (Swing1 parent, Label out) { this.parent = parent; this.out = out; }
public void actionPerformed (ActionEvent e) {
parent.count += 1;
out.setText (String.format ("%03d", parent.count));
out.repaint ();
}
}
public class Swing2 extends Frame {
public static void main (String[] args) { new Swing2 (); }
int count = 0;
public Swing2 () {
setSize (200, 100); setLayout (new FlowLayout ());
Button button = new Button ("Go"); add (button);
Label out = new Label ("000", Label.CENTER); add (out);
button.addActionListener (new ActionListener() {
public void actionPerformed (ActionEvent e) {
count += 1;
out.setText (String.format ("%03d", count));
out.repaint ();
}
});
setVisible (true);
}
}
public class Swing3 extends Frame {
public static void main (String[] args) { new Swing3 (); }
int count = 0;
public Swing3 () {
setSize (200, 100); setLayout (new FlowLayout ());
Button button = new Button ("Go"); add (button);
Label out = new Label ("000", Label.CENTER); add (out);
button.addActionListener (e -> {
count += 1;
out.setText (String.format ("%03d", count));
out.repaint ();
});
setVisible (true);
}
}
class Run1 {
public static void main (String[] args) {
for (int i = 0; i < 5; i++) {
new Thread (new MyRunnable (i)).start ();
}
}
}
class MyRunnable implements Runnable {
private int x;
public MyRunnable (int x) { this.x = x; }
public void run () {
while (true)
System.out.print (x);
}
}
3331100000000000000000000000000022222222222222224444222...
class Run2 {
public static void main (String[] args) {
for (int i = 0; i < 5; i++) {
int x = i;
new Thread (new Runnable () {
public void run () {
while (true)
System.out.print (x);
}
}).start ();
}
}
}
3331100000000000000000000000000022222222222222224444222...
class Run3 {
public static void main (String[] args) {
for (int i = 0; i < 5; i++) {
int x = i;
new Thread (() -> {
while (true)
System.out.print (x);
}).start ();
}
}
}
3331100000000000000000000000000022222222222222224444222...
class Run4 {
public static void main (String[] args) {
for (int i = 0; i < 5; i++) {
new Thread (() -> {
while (true)
System.out.print (i);
}).start ();
}
}
}
Run4.java:6: error: local variables referenced from a lambda expression must be final or effectively final
System.out.print (i);
^
class Run5 {
public static void main (String[] args) {
for (int i = 0; i < 5; i++) {
new Thread (new Runnable () {
public void run () {
while (true)
System.out.print (i);
}
}).start ();
}
}
}
Run5.java:7: error: local variables referenced from an inner class must be final or effectively final
System.out.print (i);
^
Python
import threading
for i in range(5):
def worker():
while True:
print(i, end="")
threading.Thread(target=worker).start()
4444444444444444444444444444444444444444444444444444444...
sad
Python
import threading
for i in range(5):
def worker():
x = i
while True:
print(x, end="")
threading.Thread(target=worker).start()
3331100000000000000000000000000022222222222222224444222...
Perl
use threads;
my $i;
for ($i = 0; $i < 5; $i++) {
my $th = threads->create (sub {
while (1) { print $i; }
});
$th->detach();
}
sleep (1);
5555555555555555555555555555555555555555555555555555555...
sad
Perl
use threads;
my $i;
for ($i = 0; $i < 5; $i++) {
my $x = $i
my $th = threads->create (sub {
while (1) { print $x; }
});
$th->detach();
}
sleep (1);
3331100000000000000000000000000022222222222222224444222...
Scala
for i <- (1 to 4).toList do
new Thread (() => {
while true do print (i)
}).start
3331100000000000000000000000000022222222222222224444222...
javac
(the compiler) supports nested classes
java
(the JVM) does not
$
in name
for (int i = 0; i < 5; i++) {
int x = i;
new Thread (new Runnable () {
public void run () {
while (true)
System.out.print (x);
}
}).start ();
}
$ javac Run2.java
$ javap -private 'Run2$1'
Compiled from "Run2.java"
final class Run2$1 implements java.lang.Runnable {
final int val$x;
Run2$1(int);
public void run();
}
for (int i = 0; i < 5; i++) {
new Thread (new MyRunnable (i)).start ();
}
class MyRunnable implements Runnable {
private int x;
public MyRunnable (int x) { this.x = x; }
public void run () {
while (true)
System.out.print (x);
}
}
button.addActionListener (new ActionListener() {
public void actionPerformed (ActionEvent e) {
count += 1;
out.setText (String.format ("%03d", count));
out.repaint ();
}
});
button.addActionListener (e -> {
count += 1;
out.setText (String.format ("%03d", count));
out.repaint ();
});
This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
@FunctionalInterface
annotation
java.util.function
defines many functional interfaces
java.awt.event
,
Runnable
,
Callable
, etc
@FunctionalInterface
interface Function<T,R> {
public R apply (T x);
}
Function<Integer,Integer> f = new Function<> () {
public Integer apply (Integer x) {
return x + 1;
}
};
Function<Integer,Integer> f = x -> x + 1;
map
method takes a Function
package java.util.stream;
interface Stream<T> {
...
// Returns a stream consisting of the results of applying
// the given function to the elements of this stream
<R> Stream<R> map (Function<? super T,? extends R> mapper);
...
}
Stream
view of List
in order to use map
public class Nested {
public static void main (String[] args) {
List<Integer> l = new ArrayList<> ();
Stream<Integer> s = l.stream();
l.add (1); l.add (2); l.add (3);
s.map (x -> x + 1)
.collect (Collectors.toList ())
.forEach (x -> System.out.format ("%2d ", x));
}
}
2 3 4
@FunctionalInterface
interface MouseListener { /* from java.awt.event */
void mouseClicked (MouseEvent e);
void mouseEntered (MouseEvent e);
void mouseExited (MouseEvent e);
void mousePressed (MouseEvent e);
void mouseReleased (MouseEvent e);
}
MouseListener.java:1: error: Unexpected @FunctionalInterface annotation
@FunctionalInterface
^
MouseListener is not a functional interface
multiple non-overriding abstract methods found in interface MouseListener