Sei sulla pagina 1di 313

Programmazione a

oggetti 2013

Giorgio Bruno

Dip. Automatica e Informatica


Politecnico di Torino
Tel. 011 5647003, email: giorgio.bruno@polito.it
Java
Java is
Object-oriented
Safe
Robust
Network-enabled
Write once
Graphical
run anywhere
Multithreaded
Distributed
Platform independent
http://java.sun.com/developer/onlineTraining/index.html

G. Bruno Programmazione a oggetti 2


Argomenti
Caratteristiche di base
Inheritance, interfacce, JDK
Collezioni
Testo consigliato:
Gestione eccezioni
K. Arnold, J. Gosling, D.
I/O e file
Holmes, Il linguaggio Java
Grafica, swing Manuale ufficiale. Pearson,
Applet e thread 2006.
Esempi

JDK http://www.oracle.com/technetwork/java/javase/downloads/index.html

G. Bruno Programmazione a oggetti 3


Principi della programmazione ad oggetti
Gli oggetti sono entit dinamiche, generate e distrutte nel corso
dell'esecuzione del programma.
Gli oggetti sono definiti mediante classi. Possiedono dati (attributi) ed
eseguono operazioni (metodi) su richiesta di altri oggetti.
Interazione tra due oggetti: nello svolgimento di una sua operazione un
oggetto pu richiedere l'esecuzione di un'operazione (con eventuali
parametri) da parte di un altro oggetto; il chiamante aspetta la
conclusione.
Un oggetto conosce un altro oggetto o perch gli viene passato come
parametro di un'operazione o perch ha un'associazione con esso.
Si possono stabilire associazioni (legami) tra oggetti. Si dice navigazione
il muoversi da un oggetto ad altri oggetti seguendo le loro associazioni.

G. Bruno Programmazione a oggetti 4


Classe + test
package g;
public class Point0a {
private int x,y;
public Point0a(int a, int b) {x = a; y = b;}
public void move(int a, int b) {x = a; y = b;}
public String toString(){return "x = " + x + " y = " + y;}
}

package testG;
import g.*;
public class TestPoint0a {
public static void main(String[] args) {
Point0a p = new Point0a(10,20);
p.move(100, 200);
System.out.println(p); // x = 100 y = 200
}
}
G. Bruno Programmazione a oggetti 5
classe Point0
package g;
public class Point0 {
private int x,y;
public Point0 (int a, int b) {x = a; y = b;}
public void move (int a, int b) {x = a; y = b;}
public String toString () {return "x = " + x + " y = " + y;}
public static void main (String[] args) {
Point0 p = new Point0(10,20);
p.move(100, 200);
System.out.println(p); // x = 100 y = 200
}
}

G. Bruno Programmazione a oggetti 6


Classification of OO languages (Wegner)
- Object-Based (Ada). The language has specific constructs
to manage objects
- Class-Based (CLU). + each object belongs to a class
- Object-Oriented (Simula, Smalltalk). + classes support
inheritance
- Strongly-Typed Object-Oriented (C++, Java, C#). + the
language is strongly typed

G. Bruno Programmazione a oggetti 7


Java application

Using a text editor, create a file named HelloWorldApp.java with the


following Java code:

class HelloWorldApp {
public static void main(String[] args) {
System.out.println("Hello World!"); //Display the string.
}
}

G. Bruno Programmazione a oggetti 8


Java application
Compile the source file using the Java compiler.

If the compilation succeeds, the compiler creates a file named


HelloWorldApp.class in the same directory (folder) as the Java source
file (HelloWorldApp.java). This class file contains Java bytecodes,
which are platform-independent codes interpreted by the Java
runtime system.

Run the program using the Java interpreter.

G. Bruno Programmazione a oggetti 9


Java application
class HelloWorldApp1 {
public static void main(String[] args) {
System.out.println("Hello " + args[0]);
}
}

G. Bruno Programmazione a oggetti 10


http://www.eclipse.org/downloads/ (classic) Eclipse

G. Bruno Programmazione a oggetti 11


Example
The BasicsDemo program that follows adds the numbers from 1 to 10
and displays the result.
public class BasicsDemo {
public static void main(String[] args) {
int sum = 0;
for (int current = 1; current <= 10; current++) {
sum += current;
}
System.out.println("Sum = " + sum);
}
}
The output from this program is:
Sum = 55

G. Bruno Programmazione a oggetti 12


Variables
When you declare a variable, you explicitly set the variable's
name and data type. The Java programming language has
two categories of data types: primitive and reference. A
variable of primitive type contains a value. This table shows
all of the primitive data types along with their sizes and
formats:

G. Bruno Programmazione a oggetti 13


Data types
Keyword Description Size/Format
(integers)
byte Byte-length integer 8-bit two's complement
short Short integer 16-bit two's complement
int Integer 32-bit two's complement
long Long integer 64-bit two's complement
(real numbers)
float Single-precision floating point 32-bit IEEE 754
double Double-precision floating point 64-bit IEEE 754
(other types)
char A single character 16-bit Unicode character
boolean A boolean value (true or false) true or false

G. Bruno Programmazione a oggetti 14


Scope of variables
The location of a variable declaration implicitly sets the
variable scope, which determines what section of code
may refer to the variable by its simple name. There are
four categories of scope: member variable scope, local
variable scope, parameter scope, and exception-handler
parameter scope.
You can provide an initial value for a variable within its
declaration by using the assignment operator (=).
You can declare a variable as final. The value of a final
variable cannot change after it's been initialized.

G. Bruno Programmazione a oggetti 15


Literals
int anInt = 4;
Literal Data Type
178 int
8864L long
37.266 double
37.266D double
87.363F float
26.77e3 double
' c' char
true boolean
false boolean

G. Bruno Programmazione a oggetti 16


Arithmetic operators
Operator Use Description
+ op1 + op2 Adds op1 and op2
- op1 - op2 Subtracts op2 from op1
* op1 * op2 Multiplies op1 by op2
/ op1 / op2 Divides op1 by op2
% op1 % op2 Computes the remainder of dividing op1 by op2

++ op++ Increments op by 1; evaluates to the value of op before it was


incremented
++ ++op Increments op by 1; evaluates to the value of op after it was
incremented
-- op-- Decrements op by 1; evaluates to the value of op before it was
decremented
-- --op Decrements op by 1; evaluates to the value of op after it was
decremented

G. Bruno Programmazione a oggetti 17


Relational operators
Operator Use Returns true if
> op1 > op2 op1 is greater than op2
>= op1 >= op2 op1 is greater than or equal to op2

< op1 < op2 op1 is less than op2


<= op1 <= op2 op1 is less than or equal to op2
== op1 == op2 op1 and op2 are equal
!= op1 != op2 op1 and op2 are not equal
You can use the following conditional operators to form multi-part
decisions.

G. Bruno Programmazione a oggetti 18


Operators
Operator Use Returns true if
&& op1 && op2 op1 and op2 are both true, conditionally evaluates op2
|| op1 || op2 either op1 or op2 is true, conditionally evaluates op2
! ! op op is false
& op1 & op2 op1 and op2 are both true, always evaluates op1 and op2
| op1 | op2 either op1 or op2 is true, always evaluates op1 and op2
^ op1 ^ op2 if op1 and op2 are different--that is if one or the other of the
operands is true but not both

G. Bruno Programmazione a oggetti 19


Operators
Operator Use Operation
>> op1 >> op2 shift bits of op1 right by distance op2
<< op1 << op2 shift bits of op1 left by distance op2
>>> op1 >>> op2 shift bits of op1 right by distance op2 (unsigned)
Operator Use Operation
& op1 & op2 bitwise and
| op1 | op2 bitwise or
^ op1 ^ op2 bitwise xor
~ ~op2 bitwise complement

G. Bruno Programmazione a oggetti 20


Assignments
Operator Use Equivalent to
+= op1 += op2 op1 = op1 + op2
-= op1 -= op2 op1 = op1 - op2
*= op1 *= op2 op1 = op1 * op2
/= op1 /= op2 op1 = op1 / op2
%= op1 %= op2 op1 = op1 % op2
&= op1 &= op2 op1 = op1 & op2
|= op1 |= op2 op1 = op1 | op2
^= op1 ^= op2 op1 = op1 ^ op2
<<= op1 <<= op2 op1 = op1 << op2
>>= op1 >>= op2 op1 = op1 >> op2
>>>= op1 >>>= op2 op1 = op1 >>> op2

G. Bruno Programmazione a oggetti 21


Operators

?: op1 ? op2 : op3 If op1 is true, returns op2. Otherwise, returns op3.
[] type [] Declares an array of unknown length, which contains type
elements.
[] type[op1] Creates an array with op1 elements. Must be used with the new operator.

[] op1[op2] Accesses the element at op2 index within the array op1. Indices begin at 0.

. op1.op2 Is a reference to the op2 member of op1.


() op1(params) Declares or calls the method named op1 with the specified
parameters.
(type) (type) op1 Casts (converts) op1 to type.
new new op1 Creates a new object or array.
instanceof op1 instanceof op2 Returns true if op1 is an instance of op2

G. Bruno Programmazione a oggetti 22


Control statements

while (boolean expression) {


statement(s)
}
do {
statement(s)
} while (expression);

for (initialization ; termination ; increment) {


statement(s)
}

G. Bruno Programmazione a oggetti 23


Esempi
classi g.Point, g.Rectangle, testG.TestG

G. Bruno Programmazione a oggetti 24


class Point
package g;
public class Point {
private int x,y;
public int getX() {return x;}
public int getY() {return y;}
public Point(int x, int y) {this.x = x; this.y = y;}
public void move(int x, int y) {this.x = x; this.y = y;}
public String toString(){return "x = " + x + " y = " + y;}
}

G. Bruno Programmazione a oggetti 25


class Rectangle
package g;
public class Rectangle {
private int width = 20; private int height = 10;
private Point origin = null;

public Rectangle() {origin = new Point(0, 0);}


public Rectangle(Point p, int w, int h) {
origin = p; width = w; height = h;}
public Rectangle(int w, int h) {this(new Point(0, 0), w, h);}
public String toString(){
return origin.toString()+ " w = " + width + " h = " + height;}
public void move(int x, int y) {origin.move(x,y);}
public int area() {return width * height;}
}

G. Bruno Programmazione a oggetti 26


class TestG
package testG;
import g.*;
public class TestG {
public static void main(String[] args) {
Point p1 = new Point(23, 94); System.out.println(p1.getX()); // 23
p1.move(10,20); System.out.println(p1); // x = 10 y = 20

Rectangle r1 = new Rectangle(100, 200);


r1.move(10,20);
System.out.println(r1); // x = 10 y = 20 w = 100 h = 200
System.out.println(r1.area()); // 20000
}}

G. Bruno Programmazione a oggetti 27


Packages
To make classes easier to find and use, to avoid naming conflicts, and to
control access, programmers bundle groups of related classes into
packages.
Definition: A package is a collection of related classes and interfaces
that provides access protection and namespace management.
To create a package, you simply put a class or interface in it. To do this,
you put a package statement at the top of the source file in which the
class or interface is defined. For example, the following code appears in
the source file Circle.java and puts the Circle class in the graphics
package:

package graphics;

public class Circle extends Graphic implements Draggable {

G. Bruno Programmazione a oggetti 28


Packages
However, if you are trying to use a member from a different package and
that package has not been imported, then you must use the member's
long name, which includes the package name. This is the long name for
the Rectangle class declared in the graphics package in the previous
example:
graphics.Rectangle
To import a specific member into the current file, put an import
statement at the beginning of your file before any class or interface
definitions (but after the package statement, if there is one). Here's how
you would import the Circle class from the graphics package created in
the previous section:
import graphics.Circle;
Now you can refer to the Circle class by its short name:
Circle myCircle = new Circle();

import graphics.*;

G. Bruno Programmazione a oggetti 29


Controlling Access to Members of a Class

The following chart shows the access level permitted by each specifier.
Specifier class subclass package world
private X
protected X X X
public X X X X
(package) X X

Usare metodi accessor e mutator per leggere o scrivere dati privati.

G. Bruno Programmazione a oggetti 30


Garbage collection
An object is eligible for garbage collection when there are no more references to
that object. References that are held in a variable are usually dropped when the
variable goes out of scope. Or, you can explicitly drop an object reference by setting
the variable to the special value null. Remember that a program can have multiple
references to the same object; all references to an object must be dropped before the
object is eligible for garbage collection.
The Java runtime environment has a garbage collector that periodically frees the
memory used by objects that are no longer referenced. The garbage collector does its
job automatically, although, in some situations, you may want to run the garbage
collection explicitly by calling the gc method in the System class. For instance, you
might want to run the garbage collector after a section of code that creates a large
amount of garbage or before a section of code that needs a lot of memory.
Before an object gets garbage-collected, the garbage collector gives the object an
opportunity to clean up after itself through a call to the object's finalize method. This
process is known as finalization.
Most programmers don't have to worry about implementing the finalize method. In
rare cases, however, a programmer might have to implement a finalize method to
release resources, such as native peers, that aren't under the control of the garbage
collector.

G. Bruno Programmazione a oggetti 31


Propriet di classe
Classi g.Point2, g.Rectangle2, testG.TestG2

G. Bruno Programmazione a oggetti 32


class Point2
package g;
public class Point2 {
private static int nPoints = 0;
public static int getNPoints() {return nPoints;}
public static Point2 origin = new Point2(0,0);
int x = 0; // attributi
int y = 0;
public Point2 (int a, int b) { // costruttore
x = a; y = b;
nPoints++;
}
public void move (int a, int b) {x = a; y = b;}
public String toString(){return "x = " + x + " y = " + y;}}

G. Bruno Programmazione a oggetti 33


class Rectangle2
package g;
public class Rectangle2 {
private int width = 20; private int height = 10;
private Point2 origin;
public Rectangle2() {origin = new Point2(0, 0);}
public Rectangle2(int w, int h) {this(new Point2(0, 0), w, h);}
public Rectangle2(Point2 p, int w, int h) {
origin = p; width = w; height = h;}
public String toString(){
return origin.toString()+ " w = " + width + " h = " + height;}
public void move(int x, int y) {origin.move(x,y);}
public int area() {return width * height;}
}

G. Bruno Programmazione a oggetti 34


class TestG2
package testG;
import g.*;
public class TestG2 {
public static void main(String[] args) {
Rectangle2 r = new Rectangle2(new Point2(100, 200), 10, 20);
r.move(1000,2000);
System.out.println(r); //x = 1000 y = 2000 w = 10 h = 20
System.out.println(Point2.getNPoints()); //2
}

G. Bruno Programmazione a oggetti 35


Stringhe
classi String e StringBuffer

G. Bruno Programmazione a oggetti 36


Classes String and StringBuffer
public class Stringhe {
public static String reverseIt(String source) {
int i, len = source.length();
StringBuffer dest = new StringBuffer(len);
for (i = (len - 1); i >= 0; i--) {
dest.append(source.charAt(i));
}
return dest.toString();
}
public static void main(String[] args) {
System.out.println(reverseIt("alfabeto")); // otebafla
}
}

G. Bruno Programmazione a oggetti 37


Class String
Strings are constant; their values cannot be changed
after they are created.
String c = "abc".substring(2,3);
public char charAt(int index)
public boolean equalsIgnoreCase(String anotherString)
public int compareTo(String anotherString)
public boolean startsWith(String prefix, int toffset)
public int indexOf(int ch)
public String substring(int beginIndex, int endIndex)
public int length()

G. Bruno Programmazione a oggetti 38


Class String
public final class String
extends Object
implements Serializable
The String class represents character strings. All string
literals in Java programs, such as "abc", are implemented as
instances of this class. Strings are constant; their values
cannot be changed after they are created. String buffers
support mutable strings. Because String objects are
immutable they can be shared. For example:
String str = "abc";

G. Bruno Programmazione a oggetti 39


Class String
public String(String value)
Allocates a new string that contains the same sequence of characters as the string
argument.
public String(char value[])
Allocates a new String so that it represents the sequence of characters currently
contained in the character array argument.
public String(StringBuffer buffer)
Allocates a new string that contains the sequence of characters currently contained in the
string buffer argument.
public int length()
Returns the length of this string. The length is equal to the number of 16-bit Unicode
characters in the string.
public char charAt(int index)
Returns the character at the specified index. An index ranges from 0 to length() - 1.
public boolean equals(Object anObject)
Compares this string to the specified object. The result is true if and only if the argument
is not null and is a String object that represents the same sequence of characters as this
object.

G. Bruno Programmazione a oggetti 40


Class String
public boolean equalsIgnoreCase(String anotherString)
Compares this String to another object. The result is true if and only if the argument
is not null and is a String object that represents the same sequence of characters as
this object, where case is ignored.
public int compareTo(String anotherString)
Compares two strings lexicographically. The comparison is based on the Unicode
value of each character in the strings. Returns: the value 0 if the argument string is
equal to this string; a value less than 0 if this string is lexicographically less than the
string argument; and a value greater than 0 if this string is lexicographically greater
than the string argument.
public boolean startsWith(String prefix, int toffset)
Tests if this string starts with the specified prefix.
public int hashCode() Returns a hashcode for this string.
public int indexOf(int ch)
Returns the index within this string of the first occurrence of the specified character
or -1 if the character does not occur.
public int indexOf(String str)
Returns the index within this string of the first occurrence of the specified substring.

G. Bruno Programmazione a oggetti 41


Class String
public String substring(int beginIndex)
Returns a new string that is a substring of this string. The substring begins at the
specified index and extends to the end of this string.
public String substring(int beginIndex, int endIndex)
Returns a new string that is a substring of this string. The substring begins at the
specified beginIndex and extends to the character at index endIndex - 1. Throws:
StringIndexOutOfBoundsException if the beginIndex or the endIndex is out of range.
public String replace(char oldChar, char newChar)
Returns a new string resulting from replacing all occurrences of oldChar in this string
with newChar.
public String toLowerCase()
Converts this String to lowercase.
public String trim()
Removes white space from both ends of this string.
public static String valueOf(int i) Returns the string representation of the int argument.
public static String valueOf(float f) Returns the string representation of the float
argument.

G. Bruno Programmazione a oggetti 42


Class StringBuffer
public final class StringBuffer
extends Object
implements Serializable
A string buffer implements a mutable sequence of characters. String buffers are
safe for use by multiple threads. The methods are synchronized where necessary
so that all the operations on any particular instance behave as if they occur in
some serial order.
String buffers are used by the compiler to implement the binary string
concatenation operator +. For example, the code:
x = "a" + 4 + "c" is compiled to the equivalent of:
x = new StringBuffer().append("a").append(4).append("c") .toString() The principal
operations on a StringBuffer are the append and insert methods, which are
overloaded so as to accept data of any type.
public StringBuffer(int length)
Constructs a string buffer with no characters in it and an initial capacity
specified by the length argument. Throws: NegativeArraySizeException

G. Bruno Programmazione a oggetti 43


Class StringBuffer
String palindrome = "Dot saw I was Tod";
int len = palindrome.length();
String anotherPalindrome = "Niagara. O roar again!";
char aChar = anotherPalindrome.charAt(9); //car. O
String anotherPalindrome = "Niagara. O roar again!";
String roar = anotherPalindrome.substring(11, 15); //da 11 a 15:
roar

StringBuffer sb = new StringBuffer("Drink Java!");


sb.insert(6, "Hot ");
System.out.println(sb.toString());
This code snippet prints: Drink Hot Java!
Another useful StringBuffer modifier is setCharAt, which
replaces the character at a specific location in the StringBuffer
with the character specified in the argument list.
You can use valueOf to convert variables of different types to
Strings. For example, to print the value of pi:
System.out.println(String.valueOf(Math.PI));

G. Bruno Programmazione a oggetti 44


Conversions
Converting Strings to Numbers
The String class itself does not provide any methods for
converting a String to a floating point, integer, or other
numerical type. However, four of the "type wrapper" classes
(Integer, Double, Float, and Long) provide a class method
named valueOf that converts a String to an object of that
type.

String piStr = "3.14159";


Float pi = Float.valueOf(piStr);

G. Bruno Programmazione a oggetti 45


Wrapper Classes

Boolean, Character, Double, Float, Integer, Long


ClassType(type) - constructor - Character c1 = new Character(x);
type typeValue() - char c2 = c1.charValue();
String toString()
static ClassType valueOf(String s) - genera un oggetto dalla stringa

G. Bruno Programmazione a oggetti 46


class Wrapper
package pkg1;
public class Wrapper {
public static void main(String[] args) {
Integer i0 = new Integer(10); Integer i1 = new Integer("10");
Integer i2 = Integer.valueOf("10");
int int0 = i0.intValue();
Integer i3 = 4; int k = i3; // auto boxing/unboxing
int int1 = Integer.parseInt("10");
String s1 = new String("10"); s1 = 10 +""; String s2 = String.valueOf(10);
System.out.println((i1 == i2) + " " + i1.equals(i2)); //false true
}

G. Bruno Programmazione a oggetti 47


Class Integer
java.lang.Object
| +----java.lang.Number
| +----java.lang.Integer

public final class Integer


extends Number
The Integer class wraps a value of the primitive type int in an object. An
object of type Integer contains a single field whose type is int. In addition,
this class provides several methods for converting an int to a String and a
String to an int, as well as other constants and methods useful when dealing
with an int.

G. Bruno Programmazione a oggetti 48


Class Integer
public static final int MIN_VALUE
The smallest value of type int.
public static final int MAX_VALUE
The largest value of type int.
public Integer(int value)
Constructs a newly allocated Integer object that represents the
primitive int argument.
public Integer(String s)
Constructs a newly allocated Integer object that represents the value
represented by the string. The string is converted to an int value as if
by the valueOf method.
throws NumberFormatException

G. Bruno Programmazione a oggetti 49


Class Integer
public static String toBinaryString(int i)
Creates a string representation of the integer argument as an unsigned integer
in base 2.
public static int parseInt(String s)
Parses the string argument as a signed decimal integer. The characters in the
string must all be decimal digits, except that the first character may be an ASCII
minus sign '-' to indicate a negative value.
throws NumberFormatException
public static Integer valueOf(String s)
Returns a new Integer object initialized to the value of the specified String.
Throws an exception if the String cannot be parsed as an int. The radix is
assumed to be 10.
throws NumberFormatException
public int intValue() Returns the value of this Integer as an int.
public long longValue() Returns the value of this Integer as a long.
public String toString() Returns a String object representing this Integer's value.
public boolean equals(Object obj)
Compares this object to the specified object. The result is true if and only if the
argument is not null and is an Integer object that contains the same int value as
this object.

G. Bruno Programmazione a oggetti 50


Wrapper classes
Number classes:
Number
Byte
Double
Float
Integer
Long
Short
BigDecimal
BigInteger
Wrappers for other data types (for completeness):
Boolean
Character
Void
Beyond basic arithmetic:
Math

G. Bruno Programmazione a oggetti 51


Conversioni
Integer String.valueOf
int int

intValue Integer.parseInt
Integer

String
String Integer,
toString Integer.valueOf

G. Bruno Programmazione a oggetti 52


Arrays

G. Bruno Programmazione a oggetti 53


Arrays
Here's a simple program, called ArrayDemo, that creates the array,
puts some values in it, and displays the values.
public class ArrayDemo {
public static void main(String[] args) {
int[] anArray; // declare an array of integers

anArray = new int[10]; // create an array of int

// assign a value to each array element and print


for (int i = 0; i < anArray.length; i++) {
anArray[i] = i;
System.out.print(anArray[i] + " ");
}
System.out.println();
}
}

G. Bruno Programmazione a oggetti 54


Arrays
To get the size of an array, you write
arrayname.length
Be careful: Programmers new to the Java programming
language are tempted to follow length with an empty set of
parenthesis. This doesn't work because length is not a
method. length is a property provided by the Java
platform for all arrays.
The Java programming language provides a shortcut syntax
for creating and initializing an array. Here's an example of
this syntax:
boolean[] answers = {true, false, true, true, false};

G. Bruno Programmazione a oggetti 55


Arrays
Here's a small program, ArrayOfStringsDemo that creates an array
containing three string objects then prints the strings in all lower
case letters.

public class ArrayOfStringsDemo {


public static void main(String[] args) {
String[] anArray = { "String One", "String Two",
"String Three" }; // initializer

for (int i = 0; i < anArray.length; i++) {


System.out.println(anArray[i].toLowerCase());
}
}
}
This program creates and populates the array in a single statement.

G. Bruno Programmazione a oggetti 56


Arrays
As with arrays of objects, you must explicitly create the sub-
arrays within an array. So if you don't use an initializer, you
need to write code like the following,
public class ArrayOfArraysDemo2 {
public static void main(String[] args) {
int[][] aMatrix = new int[4][];

//populate matrix
for (int i = 0; i < aMatrix.length; i++) {
aMatrix[i] = new int[5]; //create sub-array
for (int j = 0; j < aMatrix[i].length; j++) {
aMatrix[i][j] = i + j;
}
You must specify the length of the primary array when you
create the array. You can leave the length of the sub-arrays
unspecified until you create them.

G. Bruno Programmazione a oggetti 57


Matrici
public class ArrayOfArraysDemo2 {
public static void main(String[] args) {
int[][] aMatrix = new int[2][]; 0 0:0 0 0:1 0 0:0
for (int i = 0; i < aMatrix.length; i++) {
0 1:1 0 1:2 0 1:0
aMatrix[i] = new int[3];
//create sub-array 0 2:2 1 0:3 0 2:0
for (int j = 0; j < aMatrix[i].length; j++) { 1 0:1 1 1:4 1 0:0
aMatrix[i][j] = i + j; }}
printMatrix(aMatrix); 1 1:2 1 1:0
System.out.println(); 1 2:3 1 2:0
int[][] aMatrix1 = { {1,2}, {3,4} };
printMatrix(aMatrix1);
System.out.println();
int[][] aMatrix2 = new int[2][3];
printMatrix(aMatrix2);}

public static void printMatrix(int[][] aMatrix1) {


for (int i = 0; i < aMatrix1.length; i++) {
for (int j = 0; j < aMatrix1[i].length; j++) {
System.out.println("" + i + " " + j + ":" + aMatrix1[i][j]);}}}}

G. Bruno Programmazione a oggetti 58


Ereditariet
Una classe pu ereditare le propriet di un'altra classe, pu
ridefinirle e aggiungerne altre.
Polimorfismo
Dynamic binding
Down-cast

G. Bruno Programmazione a oggetti 59


Ereditariet
public int getX()
Point public int getY()
public Point(int x, int y)
public void move(int x, int
y)
IsA public String toString()
Particle public int getM()
public void setM(int m)
public Particle(int x, int y, int
m)
public String toString()

Particle eredita getX, getY, move; ridefinisce toString

G. Bruno Programmazione a oggetti 60


Particle

package g;
public class Particle extends Point {
private int m;
public int getM() {return m;}
public void setM(int m) {this.m = m;}
public Particle(int x, int y, int m) {super(x,y); this.m = m;}
public String toString(){return super.toString() + " m = " + m;}
}
Note
La prima istruzione del costruttore di Particle deve essere la chiamata di
un costruttore della classe di base.
Le propriet della classe di base non private sono accessibili mediante il
rif. super.

G. Bruno Programmazione a oggetti 61


Uso
Classi g.Particle, testG.TestParticle

G. Bruno Programmazione a oggetti 62


class TestParticle
package testG;
import g.*;
public class TestParticle {
public static void main(String[] args) {
Point p; Particle pa;
Point p1 = new Point(23, 94);
Particle pa1 = new Particle(10,20,100);
pa1.move(1,2); // metodo ereditato
System.out.println(pa1); // chiama pa1.toString() x = 1 y = 2 m = 100
p = p1; // p punta ad un point
System.out.println(p); // chiama toString() di Point x = 23 y = 94
p = pa1; // p punta ad una Particle
System.out.println(p); // chiama toString() di Particle x = 1 y = 2 m = 100
//polimorfismo: prima p punta ad un point, poi ad una Particle

G. Bruno Programmazione a oggetti 63


class TestParticle
//p definito di tipo Point, ma pu puntare anche ad oggetti di classe derivata da
// Point
//dynamic binding: la versione di toString() da chiamare dipende dal
//tipo dell'oggetto effettivamente puntato
// p.setM(10); // errore, p definito di tipo Point, quindi non vede setM
//pa = p; // inaccettabile; se pa puntasse ad un point la chiamata di pa.setM
// lecita sintatticamente, produrrebbe un errore a run-time
pa = (Particle)p; // down-cast, se il programmatore insiste
pa.setM(10); // funziona perch pa punta ad una Particle
System.out.println(pa); // x = 1 y = 2 m = 10
Point[] v = {new Point(10,20), new Particle(1,2,100), new Point(0,1)};
for (Point point:v){System.out.println(point);}
//x = 10 y = 20 x = 1 y = 2 m = 100 x = 0 y = 1
}}

G. Bruno Programmazione a oggetti 64


Omonimie
One interesting feature of Java member variables is that a
class can access a hidden member variable through its
superclass. Consider the following superclass and subclass
pair:
class A {
Integer aNumber;
}
class B extends A {
Float aNumber;
}
The aNumber variable in B hides aNumber in A. But you
can access A's aNumber from B with
super.aNumber

G. Bruno Programmazione a oggetti 65


Inheritance
A subclass inherits all of the members in its superclass that are
accessible to that subclass unless the subclass explicitly hides a member
variable or overrides a method. Note that constructors are not members
and are not inherited by subclasses.
The following list itemizes the members that are inherited by a subclass:
Subclasses inherit those superclass members declared as public or
protected.
Subclasses inherit those superclass members declared with no
access specifier as long as the subclass is in the same package as the
superclass.
Subclasses don't inherit a superclass's member if the subclass
declares a member with the same name. In the case of member
variables, the member variable in the subclass hides the one in the
superclass. In the case of methods, the method in the subclass
overrides the one in the superclass.

G. Bruno Programmazione a oggetti 66


Inheritance
A subclass cannot override methods that are declared final
in the superclass (by definition, final methods cannot be
overridden).
Also, a subclass cannot override methods that are declared
static in the superclass. In other words, a subclass cannot
override a class method. A subclass can hide a static method
in the superclass by declaring a static method in the
subclass with the same signature as the static method in the
superclass.

G. Bruno Programmazione a oggetti 67


Costruzione delloggetto di base

public Particle(int x, int y, int m) {super(x,y); this.m = m;}


La prima istruzione nel costruttore di una classe derivata deve essere la
chiamata di un costruttore della classe di base; se manca, il compilatore
inserisce la chiamata del costruttore di default.
Un costruttore pu chiamare, come prima istruzione, un altro costruttore
(della stessa classe) nel modo seguente: this()
Una classe derivata pu chiamare un metodo (ad es. M1) della classe di
base, che ha ridefinito con un suo metodo, nel modo seguente:
super.M1()
Una catena di super, come super.super.M1(), illegale.

G. Bruno Programmazione a oggetti 68


Classi astratte
public abstract class Number extends Object

public abstract double doubleValue();


Returns the value of the specified number as a double.
public abstract float floatValue();
Returns the value of the specified number as a float.
public abstract int intValue();
Returns the value of the specified number as an int.
public abstract long longValue();
Returns the value of the specified number as a long.

G. Bruno Programmazione a oggetti 69


abstract Figura Gerarchia di classi
public abstract
void disegna()

IsA IsA

Cerchio Rettangolo

public void disegna()


public void disegna()

public static void test() {


Figura[] v = {new Cerchio(), new Rettangolo()};
for (Figura f: v){ (f.disegna();}}

G. Bruno Programmazione a oggetti 70


Interfacce
Oggetti di classi differenti possono interpretare ruoli simili attraverso
un'interfaccia comune.
Un'interfaccia simile ad una classe astratta e contiene dichiarazioni
(intestazioni) di metodi.

package g;
public interface Movable {
void move(int x, int y);
}
public class Point implements Movable {
public class Rectangle implements Movable {

G. Bruno Programmazione a oggetti 71


Uso
import g.*;
public class DemoG {
public static void main(String[] args) {
Point p; Particle pa; Movable m;
Point p1 = new Point(23, 94);
Particle pa1 = new Particle(10,20,100);
Rectangle r1 = new Rectangle (1000,2000);
m = p1; m.move(1,2);
m = r1; m.move(1,2);
m = pa1; m.move(1,2);

G. Bruno Programmazione a oggetti 72


Expression Tree
public static void main(String[] args) {
Computable root = new Mult
(new Add(new Operand(10), new Operand(20)), new Operand(3));
System.out.println(root.compute());
}

Risultato: 90

Progetto Expression Tree

public interface Computable {


int compute();
}

G. Bruno Programmazione a oggetti 73


package treeClasses;
public abstract class Operator implements Computable {
Computable left, right;
public abstract int compute();}

public class Add extends Operator{


public int compute() {return left.compute() + right.compute();}
public Add(Computable left, Computable right){this.left = left; this.right = right;}}

public class Mult extends Operator{


public int compute() {return left.compute() * right.compute();}
public Mult(Computable left, Computable right){this.left = left; this.right = right;}}

public class Operand implements Computable{int value;


public int compute() {return value;}
public Operand(int value){this.value = value;}}

G. Bruno Programmazione a oggetti 74


Exceptions

G. Bruno Programmazione a oggetti 75


Exceptions
The term exception is shorthand for the phrase "exceptional
event." It can be defined as follows:

Definition: An exception is an event that occurs during the


execution of a program that disrupts the normal flow of
instructions.
The runtime system searches backwards through the call
stack, beginning with the method in which the error
occurred, until it finds a method that contains an
appropriate exception handler.

G. Bruno Programmazione a oggetti 76


Eccezioni

RuntimeException:
il compilatore non
forza il catch

G. Bruno Programmazione a oggetti 77


Grouping Error Types and Error Differentiation

Because all exceptions that are thrown within a Java


program are first-class objects, grouping or categorization of
exceptions is a natural outcome of the class hierarchy. Java
exceptions must be instances of Throwable or any Throwable
descendant. As for other Java classes, you can create
subclasses of the Throwable class and subclasses of your
subclasses. Each "leaf" class (a class with no subclasses)
represents a specific type of exception and each "node" class
(a class with one or more subclasses) represents a group of
related exceptions.

G. Bruno Programmazione a oggetti 78


Runtime Exceptions
Runtime exceptions represent problems that are detected by
the runtime system. This includes arithmetic exceptions
(such as when dividing by zero), pointer exceptions (such as
trying to access an object through a null reference), and
indexing exceptions (such as attempting to access an array
element through an index that is too large or too small).

G. Bruno Programmazione a oggetti 79


Eccezioni
public class ProvaEccezioni {

public static void main(String[] args) {


System.out.println(m1());}

static int m1(){


int i = Integer.parseInt("abc");
return i;
}
java.lang.NumberFormatException: abc
}
at java.lang.Integer.parseInt(Integer.java:426)
at java.lang.Integer.parseInt(Integer.java:476)
at ProvaEccezioni.m1(ProvaEccezioni.java:7)
at ProvaEccezioni.main(ProvaEccezioni.java:4)
Exception in thread "main"
G. Bruno Programmazione a oggetti 80
Eccezioni
public class ProvaEccezioni1 {
public static void main(String[] args) {
System.out.println(m1("abc"));}

static int m1(String s1){


int i;
try {
i = Integer.parseInt(s1);
} catch(NumberFormatException e){i = -1;}
return i;
}
}

G. Bruno Programmazione a oggetti 81


Eccezioni
public class ProvaEccezioni {

public static void main(String[] args) {


try{
System.out.println(m1("abc"));
} catch(NumberFormatException
e){System.out.println("E");}}

static int m1(String s1){


int i = Integer.parseInt(s1);
return i;
}
}

G. Bruno Programmazione a oggetti 82


Eccezioni
La classe dell'eccezione deve essere Throwable oppure una classe
derivata.
Un blocco catch pu contenere un blocco try/catch.

catch (Exception e) {
try{
System.out.println("Caught exception " + e.getMessage());
int total = 0; int correct = 10;
int n = correct/total;}
catch (Exception f){
System.out.println("Caught exception B " +
f.getMessage());}
}}

G. Bruno Programmazione a oggetti 83


Eccezioni
public static void main(String[] args) {
try{
try{
int total = 0; int correct = 10;
int n = correct/total;
} catch (Exception e) {
System.out.println("Caught exception " + e.getMessage());
int total = 0; int correct = 10;
int n = correct/total;
}
} catch (Exception f) {
System.out.println("Caught exception B " + f.getMessage());}}

G. Bruno Programmazione a oggetti 84


Eccezioni
Luso delle eccezioni evita di attribuire significati di errore ai
risultati dei metodi e costringe il chiamante ad intervenire.

static boolean passingGrade(int correct, int total)


throws Exception {
boolean Result = false;
if (correct > total) throw new Exception ("Invalid values");
if ((float)correct / (float)total > 0.7) Result = true;
return Result;
}

G. Bruno Programmazione a oggetti 85


Gestione delle eccezioni
public static void main (String[] args) {
try{
System.out.println(passingGrade(60,80));
System.out.println(passingGrade(80,60));
System.out.println(passingGrade(40,80)); //never gets
executed
} catch (Exception e) {
System.out.println("Caught exception " + e.getMessage());
}}
Output:

G. Bruno Programmazione a oggetti 86


Test
Question: Is the following code legal?
try {
...
} finally {
...
}
Question: What exceptions can be caught by the
following handler?
...
} catch (Exception e) {
...
} catch (ArithmeticException a) {
...
}

G. Bruno Programmazione a oggetti 87


Test
Question: Match each situation in the first column with an item in the second
column. (1: error, 2: checked exception, 3: runtime exception, 4: no exception)
1. int[] A; A[0] = 0;
2. The Java VM starts running your program, but the VM cant find the Java
platform classes. (The Java platform classes reside in classes.zip or rt.jar.)
3. A program is reading a stream and reaches the end of stream marker.
4. Before closing the stream and after reaching the end of stream marker, a program
tries to read the stream again.
Answer:
1. 3 (runtime exception).
2. 1 (error).
3. 4 (no exception). When you read a stream, you expect there to be an end of
stream marker. You should use exceptions to catch unexpected behavior in
your program.
4. 2 (checked exception).

G. Bruno Programmazione a oggetti 88


Class Object
The Object class sits at the top of the class hierarchy tree in the Java
platform. Every class in the Java system is a descendent, direct or
indirect, of the Object class. This class defines the basic state and
behavior that all objects must have, such as the ability to compare
oneself to another object, to convert to a string, to wait on a condition
variable, to notify other objects that a condition variable has changed,
and to return the class of the object.
Your classes may want to override the following Object methods.
clone
equals, hashCode
finalize - chiamato prima della garbage collection
toString
Your class cannot override these Object methods (they are final):
getClass, notify, notifyAll, wait

G. Bruno Programmazione a oggetti 89


Class Object
public final native Class getClass()
Returns the object of type Class that represents the runtime class of the
object.
public native int hashCode()
Returns a hash code value for the object. This method is supported for the
benefit of hashtables such as those provided by java.util.Hashtable.
public boolean equals(Object obj)
Compares two Objects for equality.
protected native Object clone() throws CloneNotSupportedException
Creates a new object of the same class as this object. It then initializes each
of the new object's fields by assigning it the same value as the
corresponding field in this object. No constructor is called. The clone method
of class Object will only clone an object whose class indicates that it is
willing for its instances to be cloned. A class indicates that its instances can
be cloned by declaring that it implements the Cloneable interface.

G. Bruno Programmazione a oggetti 90


Class Object
public String toString()
Returns a string representation of the object. In general, the toString
method returns a string that "textually represents" this object. The
result should be a concise but informative representation that is easy for
a person to read. It is recommendedthat all subclasses override this
method.

protected void finalize() throws Throwable


Called by the garbage collector on an object when garbage collection
determines that there are no more references to the object. A subclass
overrides the finalize method to dispose of system resources or to
perform other cleanup.

G. Bruno Programmazione a oggetti 91


Class Object from http://download.oracle.com/javase/6/docs/api/java/lang/Object.html

Method Summary
protected Object clone()
Creates and returns a copy of this object.
boolean equals(Object obj)
Indicates whether some other object is "equal to" this one.
protected void finalize()
Called by the garbage collector on an object when garbage collection determines
that there are no more references to the object.
Class<?> getClass()
Returns the runtime class of this Object.
int hashCode()
Returns a hash code value for the object.
void notify()
Wakes up a single thread that is waiting on this object's monitor.
void notifyAll()
Wakes up all threads that are waiting on this object's monitor.
String toString()
Returns a string representation of the object.
void wait()
Causes the current thread to wait until another thread invokes the notify() method or
the notifyAll() method for this object.
void wait(long timeout)
Causes the current thread to wait until either another thread invokes the notify()
method or the notifyAll() method for this object, or a specified amount of time has
elapsed.
void wait(long timeout, int nanos)
Causes the current thread to wait until another thread invokes the notify() method or
the notifyAll() method for this object, or some other thread interrupts the current thread,
or a certain amount of real time has elapsed.
G. Bruno Programmazione a oggetti 92
equals
package g;
public class Point {
private int x,y;
public int getX() {return x;}
public int getY() {return y;}
public Point(int x, int y) {this.x = x; this.y = y;}
public void move(int x, int y) {this.x = x; this.y = y;}
public String toString(){return "x = " + x + " y = " + y;}
public boolean equals (Object o) {
if (!(o instanceof Point)) return false;
Point p = (Point)o; return this.x == p.x && this.y == p.y;}
public boolean isEqualTo(Point p) {
return this.x == p.x && this.y == p.y;}}

G. Bruno Programmazione a oggetti 93


class TestEquals
package testG;
import g.*;
public class TestEquals {
public static void main(String[] args) {
Point p1 = new Point(23, 94);
p1.move(10,20);
Point p2 = new Point(10, 20);
System.out.println(p1.equals(p2)); // true
System.out.println(p1 == p2); // false
System.out.println(p1.equals(10)); // false
System.out.println(p1.isEqualTo(p2)); // true
}
}

G. Bruno Programmazione a oggetti 94


Esempi di clonazione
Classi g.Point1, g.Rectangle1, testG.TestG1

G. Bruno Programmazione a oggetti 95


class Point1
package g;
public class Point1 implements Cloneable {
private int x,y;
public int getX() {return x;}
public int getY() {return y;}
public Point1(int x, int y) {this.x = x; this.y = y;}
public void move(int x, int y) {this.x = x; this.y = y;}
public String toString(){return "x = " + x + " y = " + y;}
public Object clone(){
try {return super.clone();}
catch (CloneNotSupportedException e) {return null;}}
}

Nota: si tratta di una classe i cui attributi contengono valori (tipi


primitivi).

G. Bruno Programmazione a oggetti 96


class Rectangle1
package g;
public class Rectangle1 implements Cloneable{
private int width = 20; private int height = 10;
private Point1 origin;
public Rectangle1() {origin = new Point1(0, 0);}
public Rectangle1(int w, int h) {this(new Point1(0, 0), w, h);}
public Rectangle1(Point1 p, int w, int h) {origin = p; width = w; height = h;}
public String toString(){ return origin.toString()+ " w = " + width + " h = " + height;}
public void move(int x, int y) {origin.move(x,y);}
public int area() {return width * height;}
public Object clone(){
try {Rectangle1 r = (Rectangle1)super.clone();
r.origin = (Point1)origin.clone();return r;}
catch (CloneNotSupportedException e) {return null;}}
}
Nota: l'attributo origin un riferimento.

G. Bruno Programmazione a oggetti 97


class TestG1
package testG;
import g.*;
public class TestG1 {
public static void main(String[] args) {
Point1 p1 = new Point1(23, 94);
Point1 p2 = (Point1) p1.clone(); p2.move(10,20);
System.out.println(p1); // x = 23 y = 94
System.out.println(p2); // x = 10 y = 20
Rectangle1 r1 = new Rectangle1(100, 200);
Rectangle1 r2 = (Rectangle1) r1.clone(); r2.move(10,20);
System.out.println(r1); // x = 0 y = 0 w = 100 h = 200
System.out.println(r2);// x = 10 y = 20 w = 100 h = 200
}}

G. Bruno Programmazione a oggetti 98


getClass
The getClass method is a final method that returns a runtime representation of
the class of an object. This method returns a Class object.
Once you have a Class object you can query it for various information about the
class, such as its name, its superclass, and the names of the interfaces that it
implements. The following method gets and displays the class name of an object:
void PrintClassName(Object obj) {
System.out.println("The Object's class is " +
obj.getClass().getName());
}
One handy use of a Class object is to create a new instance of a class without
knowing what the class is at compile time. The following sample method creates
a new instance of the same class as obj, which can be any class that inherits from
Object (which means that it could be any class):
Object createNewInstanceOf(Object obj) { return
obj.getClass().newInstance();}

public Object newInstance() throws InstantiationException, IllegalAccessException

G. Bruno Programmazione a oggetti 99


Uso di Class
import g.*;
public class DemoG2 {
public static void main(String[] args) {
Rectangle r1 = new Rectangle(100,200);
Class c1 = r1.getClass();
System.out.println(c1.getName()); // g.Rectangle
try{
Rectangle r2 = (Rectangle)c1.newInstance();
System.out.println(r2); // x = 0 y = 0 w = 20 h = 10
Class c2 = Class.forName("g.Particle");
System.out.println(c2); // class g.Particle
System.out.println(c2.getSuperclass()); // class g.Point
} catch(Exception e) {System.out.println(e);}

G. Bruno Programmazione a oggetti 100


hashCode e toString
public class Info {
int val;
public Info(int val) {this.val = val;}
}
public class InfoTest {
public static void main(String[] args) {
Info a = new Info(10);
Info b = new Info(10);
System.out.println(a.hashCode());
System.out.println(b.hashCode()); 17523401
System.out.println(a); 8567361
System.out.println(b); Info@10b62c9
}}
Info@82ba41

G. Bruno Programmazione a oggetti 101


hashCode e toString
public class Info {
int val;
public Info(int val) {this.val = val;}
public int hashCode() {return val;}
public String toString() {return String.valueOf(val);}
}
public class InfoTest {
public static void main(String[] args) {
Info a = new Info(10);
Info b = new Info(10);
System.out.println(a.hashCode()); 10
System.out.println(b.hashCode()); 10
System.out.println(a); 10
System.out.println(b);
10
}}

G. Bruno Programmazione a oggetti 102


JDK
java.lang: wrappers for basic data types and strings; threads;
mathematical operations; exceptions; the System class; and the Object
base class.
java.io: Classes for controlling file and stream operations.
java.util: a class for manipulating dates; basic data structure classes,
such as hash tables and stacks; a tool for parsing Strings.
java.applet: This package contains the Applet class.
java.awt: The AWT (Abstract Window Toolkit) package provides simple
and advanced tools used to direct the visual interface of a Java applet.

G. Bruno Programmazione a oggetti 103


Class System
System.runFinalization(); This method calls the finalize
methods on all objects that are waiting to be garbage
collected.
System.gc(); Running the Garbage Collector.
byte[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e', 'i', 'n', 'a', 't', 'e', 'd' };
byte[] copyTo = new byte[7];
System.arraycopy(copyFrom, 2, copyTo, 0, 7);
long clickTime = System.currentTimeMillis();
System.exit(-1); // status code <> 0 terminazione anormale

G. Bruno Programmazione a oggetti 104


Class System
The following program, ArrayCopyDemo, uses arraycopy to copy
some elements from the copyFrom array to the copyTo array.
public class ArrayCopyDemo {
public static void main(String[] args) {
char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e',
'i', 'n', 'a', 't', 'e', 'd' };
char[] copyTo = new char[7];

System.arraycopy(copyFrom, 2, copyTo, 0, 7);


System.out.println(new String(copyTo));
}
}
The arraycopy method call in this example program begins the
copy at element number 2 in the source array.

Output: caffein

G. Bruno Programmazione a oggetti 105


Classe Math

Math Class (final con metodi statici)


come ad esempio static double sin(double a)

public long uniform(long l, long h) {


double d = Math.random() ;
return Math.round(l + d * (h - l)); }

G. Bruno Programmazione a oggetti 106


Tipi generici
package generici;
public interface Queue <E> {
boolean put (E v);
E get ();
int size();
}

G. Bruno Programmazione a oggetti 107


class SimpleQueue
package generici;
@SuppressWarnings("unchecked")
public class SimpleQueue <E> implements Queue <E>{
int size; protected E[] b; protected int iw, ir;
private int occupiedSlots = 0;
public SimpleQueue (int size) {b = (E[])new Object[size]; this.size = size;}
private void write (E v) {b[iw] = v; iw = (iw + 1) % size; occupiedSlots++;}
private E read () {E v = b[ir]; ir = (ir + 1) % size; occupiedSlots--;
return v;}
public boolean put (E v) {boolean res = occupiedSlots < size;
if (res) write(v); return res;}
public E get () {E res = null; if (occupiedSlots > 0) res = read();return res;}
public int size() {return occupiedSlots;}}
buffer
circolare
G. Bruno Programmazione a oggetti 108
TestQueue
package generici;
public class TestQueue {
public static void main(String[] args) {
SimpleQueue<Integer> q1 = new SimpleQueue<Integer>(3);
q1.put(1); q1.put(2);
System.out.println(q1.get()); //1
SimpleQueue<String> q2 = new SimpleQueue<String>(3);
q2.put("alfa"); q2.put("beta");
System.out.println(q2.get()); //alfa
System.out.println(q2.size()); //1
}
}

G. Bruno Programmazione a oggetti 109


SimpleQueue1
package generici;
import java.util.*;
@SuppressWarnings("unchecked")
public class SimpleQueue1<E> extends SimpleQueue<E>{
public SimpleQueue1(int size) {super(size);}
public Enumeration<E> enumerator() {return new QueueEnum<E>();}
private class QueueEnum<T> implements Enumeration<T> {
int i = ir;
public boolean hasMoreElements() {return (i != iw);}
public T nextElement() {
if (!hasMoreElements())
throw new NoSuchElementException();
else return (T)b[i++];
}
}
}

G. Bruno Programmazione a oggetti 110


Nested Classes
Java lets you define a class as a member of another class. Such a class is
called a nested class and is illustrated here:
class EnclosingClass{
...
class ANestedClass {
...
}
}

Definition: A nested class is a class that is a member of another class.

G. Bruno Programmazione a oggetti 111


Interface Enumeration<E>

boolean hasMoreElements()
Tests if this enumeration contains more elements.
E nextElement()
Returns the next element of this enumeration if this enumeration
object has at least one more element to provide.

G. Bruno Programmazione a oggetti 112


TestQueue1
package generici; import java.util.*;
public class TestQueue1 {
public static double getSum(SimpleQueue1<? extends Number> q) {
double sum = 0.0;
for (Enumeration<? extends Number> e = q.enumerator(); e.hasMoreElements();) {
sum += e.nextElement().doubleValue();}
return sum;}
public static void main(String[] args) {
SimpleQueue1<Integer> q1 = new SimpleQueue1<Integer>(3);
q1.put(1); q1.put(2);
for (Enumeration<Integer> e = q1.enumerator(); e.hasMoreElements();) { 1
System.out.println(e.nextElement()); 2
} 3.0
System.out.println(getSum(q1));
SimpleQueue<String> q2 = new SimpleQueue<String>(3);q2.put("alfa"); q2.put("beta");
//System.out.println(getSum(q2));
//errore The method getSum(SimpleQueue1<? extends Number>) in the type TestQueue1
//is not applicable for the arguments (SimpleQueue<String>)
}}

G. Bruno Programmazione a oggetti 113


Collections

G. Bruno Programmazione a oggetti 114


Collections
A collection is simply an object that groups multiple elements into a single
unit. Collections are used to store, retrieve and manipulate data, and to
transmit data from one method to another. Collections typically represent
data items that form a natural group, like a poker hand (a collection of
cards), a mail folder (a collection of letters), or a telephone directory (a
collection of name-to-phone-number mappings). A collections framework is a
unified architecture for representing and manipulating collections. All
collections frameworks contain three things:
Interfaces: abstract data types representing collections. Interfaces allow collections
to be manipulated independently of the details of their representation. In object-
oriented languages like Java, these interfaces generally form a hierarchy.
Implementations: concrete implementations of the collection interfaces. In essence,
these are reusable data structures.
Algorithms: methods that perform useful computations, like searching and sorting,
on objects that implement collection interfaces. These algorithms are said to be
polymorphic because the same method can be used on many different
implementations of the appropriate collections interface. In essence, algorithms are
reusable functionality.

G. Bruno Programmazione a oggetti 115


Collezioni

Interface Implementation Historical

Set HashSet TreeSet

List ArrayList LinkedList Vector


Stack

Map HashMap TreeMap Hashtable


Properties

Collection Iterator,
ListIterator
G. Bruno Programmazione a oggetti 116
Collections
The two general purpose Set implementations are HashSet and TreeSet. It's very
straightforward to decide which of these two to use. HashSet is much faster
(constant time vs. log time for most operations), but offers no ordering
guarantees. If you need to use the operations in the SortedSet, or in-order
iteration is important to you, use TreeSet. Otherwise, use HashSet.
The two general purpose List implementations are ArrayList and LinkedList.
Most of the time, you'll probably use ArrayList. It offers constant time positional
access, and it's just plain fast, because it does not have to allocate a node object
for each element in the List, and it can take advantage of the native method
System.arraycopy when it has to move multiple elements at once. Think of
ArrayList as Vector without the synchronization overhead. ArrayList has one
tuning parameter, the initial capacity.
The two general purpose Map implementations are HashMap and TreeMap. The
situation for Map is exactly analogous to Set. If you need SortedMap operations
or in-order Collection-view iteration, go for TreeMap; otherwise, go for HashMap.
Everything else in the Set section also applies to Map so just re-read it.

G. Bruno Programmazione a oggetti 117


Interface Set<E>, Interface Collection<E>
boolean add(E e) Ensures that this collection contains the specified element.
boolean addAll(Collection<? extends E> c)
Adds all of the elements in the specified collection to this
collection.
void clear() Removes all of the elements from this collection.
boolean contains(Object o) Returns true if this collection contains the specified element.
boolean containsAll(Collection<?> c)
Returns true if this collection contains all of the elements in the
specified collection.
boolean equals(Object o)
int hashCode()
boolean isEmpty() Returns true if this collection contains no elements.
Iterator<E> iterator() Returns an iterator over the elements in this collection.
boolean remove(Object o) Removes a single instance of the specified element from this
collection, if it is present.

G. Bruno Programmazione a oggetti 118


Set, Collection
boolean removeAll(Collection<?> c)
Removes all of this collection's elements that are also contained in the specified
collection.
boolean retainAll(Collection<?> c)
Retains only the elements in this collection that are contained in the specified
collection.
int size()
Returns the number of elements in this collection.
Object[] toArray()
Returns an array containing all of the elements in this collection.
<T> T[] toArray(T[] a)
Returns an array containing all of the elements in this collection;
the runtime type of the returned array is that of the specified array.

G. Bruno Programmazione a oggetti 119


Sets
A Set is a Collection that cannot contain duplicate elements. Set models
the mathematical set abstraction. The Set interface extends Collection
and contains no methods other than those inherited from Collection.
The JDK contains two general-purpose Set implementations. HashSet,
which stores its elements in a hash table, is the best-performing
implementation. TreeSet, which stores its elements in a red-black tree,
guarantees the order of iteration.

G. Bruno Programmazione a oggetti 120


Bulk operations
The bulk operations are particularly well suited to Sets: they perform standard
set-algebraic operations. Suppose s1 and s2 are Sets. Here's what the bulk
operations do:
s1.containsAll(s2): Returns true if s2 is a subset of s1. (For example, set s1 is a
subset of s2 if set s2 contains all the elements in s1.)
s1.addAll(s2): Transforms s1 into the union of s1 and s2. (The union of two sets
is the set containing all the elements contained in either set.)
s1.retainAll(s2): Transforms s1 into the intersection of s1 and s2. (The
intersection of two sets is the set containing only the elements that are common
in both sets.)
s1.removeAll(s2): Transforms s1 into the (asymmetric) set difference of s1 and
s2. (For example, the set difference of s1 - s2 is the set containing all the
elements found in s1 but not in s2.)
s1.clear(): Removes all elements.
The addAll, removeAll, and retainAll methods all return true if the target
Collection was modified in the process of executing the operation.

G. Bruno Programmazione a oggetti 121


Interface Iterator<E>
boolean hasNext()
Returns true if the iteration has more elements.
E next()
Returns the next element in the iteration.
Throws: NoSuchElementException - iteration has no more
elements.
void remove()
Removes from the underlying collection the last element returned by the
iterator.
Throws: IllegalStateException - if the next method has not yet been
called, or the remove method has already been called after the last call to
the next method.

G. Bruno Programmazione a oggetti 122


Esempio
package collezioni;
import java.util.*;
public class Collezioni1 {
public static void main(String[] args) {
Set<String> hs; hs = new HashSet<String>();
Set<String> ripetuti = new TreeSet<String>();
String[] v = {"alfa", "beta", "alfa", "delta"};
for (String s:v) if (!hs.add(s)) ripetuti.add(s);
System.out.println(hs + " " + ripetuti); // [alfa, delta, beta] [alfa]
System.out.println(hs.contains("gamma")); // false
System.out.println(hs.containsAll(ripetuti)); // true

G. Bruno Programmazione a oggetti 123


Esempio
Object[] v1 = hs.toArray();
System.out.println(Arrays.toString(v1)); // [alfa, delta, beta]
String[] v2 = new String[hs.size()];
hs.toArray(v2);
System.out.println(Arrays.toString(v2)); // [alfa, delta, beta]
Set<String> hs1; hs1 = new HashSet<String>();
hs1.addAll(Arrays.asList(v2));
System.out.println(hs1); // [alfa, delta, beta]
// iterazioni su set
for (String s: hs) System.out.println(s);
for (Iterator<String> it = hs.iterator(); it.hasNext();)
System.out.println(it.next());
System.out.println(hs.remove("alfa")); // true
}}

G. Bruno Programmazione a oggetti 124


Costruttori di HashSet
HashSet()
Constructs a new, empty set; the backing HashMap instance has
default initial capacity (16) and load factor (0.75).
HashSet(Collection<? extends E> c)
Constructs a new set containing the elements in the specified
collection.
HashSet(int initialCapacity)
Constructs a new, empty set; the backing HashMap instance has
the specified initial capacity and default load factor (0.75).
HashSet(int initialCapacity, float loadFactor)
Constructs a new, empty set; the backing HashMap instance has
the specified initial capacity and the specified load factor.

G. Bruno Programmazione a oggetti 125


Costruttori di TreeSet
TreeSet()
Constructs a new, empty tree set, sorted according to the natural
ordering of its elements.
TreeSet(Collection<? extends E> c)
Constructs a new tree set containing the elements in the
specified collection, sorted according to the natural ordering of its
elements.
TreeSet(Comparator<? super E> comparator)
Constructs a new, empty tree set, sorted according to the
specified comparator.
TreeSet(SortedSet<E> s)
Constructs a new tree set containing the same elements and
using the same ordering as the specified sorted set.

G. Bruno Programmazione a oggetti 126


Natural ordering
public interface Comparable<T>
This interface imposes a total ordering on the objects of each class that
implements it. This ordering is referred to as the class's natural ordering, and
the class's compareTo method is referred to as its natural comparison method.
Lists (and arrays) of objects that implement this interface can be sorted
automatically by Collections.sort (and Arrays.sort). Objects that implement this
interface can be used as keys in a sorted map or as elements in a sorted set,
without the need to specify a comparator.
The natural ordering for a class C is said to be consistent with equals if and only
if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every
e1 and e2 of class C. Note that null is not an instance of any class, and
e.compareTo(null) should throw a NullPointerException even though
e.equals(null) returns false.

int compareTo(T o)
Compares this object with the specified object for order. Returns a negative
integer, zero, or a positive integer as this object is less than, equal to, or greater
than the specified object.

G. Bruno Programmazione a oggetti 127


Ordinamento
Un HashSet aggiunge un nuovo elemento se il suo hashCode
diverso da quelli gi presenti oppure se equals falso per
tutti gli oggetti di pari hashCode.
Per avere gli elementi ordinati occorre usare un TreeSet e
implementare l'interfaccia Comparable (e quindi il metodo
compareTo).

G. Bruno Programmazione a oggetti 128


class Point estesa
package collezioni;
public class Point implements Comparable<Point> {
private int x,y;
public int getX() {return x;} public int getY() {return y;}
public Point(int x, int y) {this.x = x; this.y = y;}
public void move(int x, int y) {this.x = x; this.y = y;}
public String toString(){return "x = " + x + " y = " + y;}
public boolean equals (Object o) {
if (!(o instanceof Point)) return false;
Point p = (Point)o; return this.x == p.x && this.y == p.y;}
public int hashCode () {return this.x + 31 * this.y;}
public int compareTo (Point p) { // increasing x incr y
if (this.x == p.x) {
if (this.y == p.y) return 0;
else if (this.y < p.y) return -1;
else return 1;
} else {
if (this.x < p.x) return -1;
else return 1;} } }

G. Bruno Programmazione a oggetti 129


class PointComparator
package collezioni;
import java.util.Comparator;
public class PointComparator implements Comparator<Point>{
public int compare(Point p1, Point p2){
if (p1.getX() == p2.getX())
return (p2.getY() < p1.getY()? -1 : 1);
else return (p2.getX() < p1.getX()? -1 : 1);
}
}

G. Bruno Programmazione a oggetti 130


Test
package collezioni;
import java.util.*;
public class Collezioni2 {
public static void main(String[] args) {
Set<Point> ps = new HashSet<Point>();
ps.add(new Point(10,20)); ps.add(new Point(15,25));
ps.add(new Point(5,25)); ps.add(new Point(10,20));
ps.add(new Point(15,30));
System.out.println(ps);
// [x = 15 y = 25, x = 10 y = 20, x = 5 y = 25, x = 15 y = 30]
Set<Point> ps1 = new TreeSet<Point>(ps);
System.out.println(ps1);
// [x = 5 y = 25, x = 10 y = 20, x = 15 y = 25, x = 15 y = 30]
PointComparator comp = new PointComparator();
Set<Point> ps2 = new TreeSet<Point>(comp);
for (Point p: ps) ps2.add(p);
System.out.println(ps2);
// [x = 15 y = 30, x = 15 y = 25, x = 10 y = 20, x = 5 y = 25]}}

G. Bruno Programmazione a oggetti 131


Class TreeSet<E>
Class TreeSet<E> implements
Collection<E>, NavigableSet<E>, Set<E>, SortedSet<E>

public interface NavigableSet<E>


extends SortedSet<E>

G. Bruno Programmazione a oggetti 132


SortedSet<E>
E first()
Returns the first (lowest) element currently in this set.
SortedSet<E> headSet(E toElement)
Returns a view of the portion of this set whose elements are strictly less
than toElement.
E last()
Returns the last (highest) element currently in this set.
SortedSet<E> subSet(E fromElement, E toElement)
Returns a view of the portion of this set whose elements range from
fromElement, inclusive, to toElement, exclusive.
SortedSet<E> tailSet(E fromElement)
Returns a view of the portion of this set whose elements are greater
than or equal to fromElement.

G. Bruno Programmazione a oggetti 133


List
A List is an ordered Collection(sometimes called a sequence). Lists may contain
duplicate elements. In addition to the operations inherited from Collection, the
List interface includes operations for:
Positional Access: manipulate elements based on their numerical position in
the list.
Search: search for a specified object in the list and return its numerical position.
List Iteration: extend Iterator semantics to take advantage of the list's
sequential nature.
Range-view: perform arbitrary range operations on the list.
The JDK contains two general-purpose List implementations. ArrayList, which
is generally the best-performing implementation, and LinkedList which offers
better performance under certain circumstances.

G. Bruno Programmazione a oggetti 134


Interface List<E>
boolean add(E e)
void add(int index, E element)
Inserts the specified element at the specified position.
boolean addAll(Collection<? extends E> c)
boolean addAll(int index, Collection<? extends E> c)
Inserts all of the elements of c at the specified position.
void clear()
boolean contains(Object o)
boolean containsAll(Collection<?> c)
boolean equals(Object o)
E get(int index) Returns the element at the specified position.
int hashCode()
int indexOf(Object o) Returns the index of the first occurrence of the specified
element in this list, or -1 if this list does not contain the element.
boolean isEmpty()

G. Bruno Programmazione a oggetti 135


List
Iterator<E> iterator()
int lastIndexOf(Object o)
Returns the index of the last occurrence of the specified element in this list, or -1
if this list does not contain the element.
ListIterator<E> listIterator() Returns a list iterator over the elements in this list.
ListIterator<E> listIterator(int index)
Returns a list iterator of the elements in this list, starting at the specified
position.
E remove(int index) Removes the element at the specified position.
boolean remove(Object o) boolean removeAll(Collection<?> c)
boolean retainAll(Collection<?> c)
E set(int index, E element) Replaces the element at the specified position with
element.
int size()
List<E> subList(int fromIndex, int toIndex)
Returns a view of the portion of this list between the specified fromIndex,
inclusive, and toIndex, exclusive.
Object[] toArray() <T> T[] toArray(T[] a)

G. Bruno Programmazione a oggetti 136


Liste
package collezioni; import java.util.*;
public class ListExample {
public static void main(String args[]) {
List<String> list = new ArrayList<String>();
list.add("Bernadine"); list.add("Elizabeth"); list.add("Gene");
list.add("Elizabeth"); list.add("Clara");
System.out.println(list); // [Bernadine, Elizabeth, Gene, Elizabeth, Clara]
System.out.println("2: " + list.get(2)); // 2: Gene
System.out.println("0: " + list.get(0)); // 0: Bernadine
LinkedList<String> queue = new LinkedList<String>();
queue.addFirst("Bernadine"); queue.addFirst("Elizabeth");
queue.addFirst("Gene"); queue.addFirst("Elizabeth"); queue.addFirst("Clara");
System.out.println(queue); // [Clara, Elizabeth, Gene, Elizabeth, Bernadine]
queue.removeLast(); queue.removeLast();
System.out.println(queue); // [Clara, Elizabeth, Gene]

G. Bruno Programmazione a oggetti 137


Liste
for (ListIterator<String> i=queue.listIterator(queue.size()); i.hasPrevious();)
System.out.println(i.previous()); // Gene Elizabeth Clara
// replacing names starting with E
for (ListIterator<String> i=queue.listIterator(); i.hasNext();)
if(i.next().startsWith("E")) i.remove();
System.out.println(queue); //[Clara, Gene]
// swapping the two elements
String s = queue.get(0); queue.set(0,queue.get(1)); queue.set(1,s);
System.out.println(queue); // [Gene, Clara]
}
}

G. Bruno Programmazione a oggetti 138


Costruttori
ArrayList()
Constructs an empty list with an initial capacity of ten.
ArrayList(Collection<? extends E> c)
Constructs a list containing the elements of the specified collection,
in the order they are returned by the collection's iterator.
ArrayList(int initialCapacity)
Constructs an empty list with the specified initial capacity.

LinkedList()
Constructs an empty list.
LinkedList(Collection<? extends E> c)
Constructs a list containing the elements of the specified collection,
in the order they are returned by the collection's iterator.

G. Bruno Programmazione a oggetti 139


Interface ListIterator<E>
void add(E e) Inserts the specified element into the list.
boolean hasNext() Returns true if this list iterator has more elements
when traversing the list in the forward direction.
boolean hasPrevious() Returns true if this list iterator has more elements
when traversing the list in the reverse direction.
E next() Returns the next element in the list.
int nextIndex() Returns the index of the element that would be
returned by a subsequent call to next.
E previous() Returns the previous element in the list.
int previousIndex() Returns the index of the element that would be
returned by a subsequent call to previous.
void remove() Removes from the list the last element that was
returned by next or previous.
void set(E e) Replaces the last element returned by next or
previous with the specified element.

G. Bruno Programmazione a oggetti 140


Sorting
package collezioni;
import java.util.*;
public class Collezioni3 {
public static void main(String[] args) {
List<String> l1 = new ArrayList<String>();
Collections.addAll(l1, "beta", "alfa", "delta");
Collections.sort(l1); System.out.println(l1); // [alfa, beta, delta]
//descending order
Comparator<String> comp = new Comparator<String>() { anonymous
public int compare(String s1, String s2) {return s2.compareTo(s1);}}; class
Collections.sort(l1,comp); System.out.println(l1); // [delta, beta, alfa]
System.out.println(Collections.binarySearch(l1, "beta")); // 1
System.out.println(Collections.binarySearch(l1, "gamma")); // -4
System.out.println(Collections.max(l1)); // delta
System.out.println(Collections.frequency(l1, "alfa")); // 1
Collections.shuffle(l1, new Random());

G. Bruno Programmazione a oggetti 141


Sorting
List<Point> l2 = new ArrayList<Point>();
l2.add(new Point(10,20)); l2.add(new Point(15,25));
l2.add(new Point(5,25)); l2.add(new Point(15,30));
Collections.sort(l2);
System.out.println(l2);
// [x = 5 y = 25, x = 10 y = 20, x = 15 y = 25, x = 15 y = 30]
System.out.println(Collections.binarySearch(l2, new Point(10,20))); // 1
PointComparator comp1 = new PointComparator();
Collections.sort(l2, comp1);
System.out.println(l2);
// [x = 15 y = 30, x = 15 y = 25, x = 10 y = 20, x = 5 y = 25]
System.out.println(Collections.binarySearch(l2, new Point(10,20),
comp1)); // 2
}}

G. Bruno Programmazione a oggetti 142


Algorithms
The polymorphic algorithms described in this section are pieces of reusable
functionality provided by the JDK. All of them come from the Collections class.
All take the form of static methods whose first argument is the collection on
which the operation is to be performed. The great majority of the algorithms
provided by the Java platform operate on List objects, but a couple of them (min
and max) operate on arbitrary Collection objects.

Searching
The binarySearch algorithm searches for a specified element in a sorted List
using the binary search algorithm.
The following idiom, usable with both forms of the binarySearch operation, looks
for the specified search key, and inserts it at the appropriate position if it's not
already present:
int pos = Collections.binarySearch(l, key);
if (pos < 0)
l.add(-pos-1, key);

G. Bruno Programmazione a oggetti 143


Class Collections
static <T> boolean addAll(Collection<? super T> c, T... elements)
Adds all of the specified elements to the specified collection.
static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
Searches the specified list for the specified object using the binary search algorithm.
static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)
Searches the specified list for the specified object using the binary search algorithm.
static <T> void copy(List<? super T> dest, List<? extends T> src)
Copies all of the elements from one list into another.
static <T> void fill(List<? super T> list, T obj)
Replaces all of the elements of the specified list with the specified element.
static int frequency(Collection<?> c, Object o)
Returns the number of elements in the specified collection equal to the specified object.
static <T> T max(Collection<? extends T> coll) // also for min
Returns the maximum element, according to the natural ordering of its elements.
static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp)
Returns the maximum element, according to the order induced by the specified comparator.

G. Bruno Programmazione a oggetti 144


Class Collections
static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)
Replaces all occurrences of one specified value in a list with another.
static void reverse(List<?> list)
Reverses the order of the elements in the specified list.
static void shuffle(List<?> list)
Randomly permutes the specified list using a default source of randomness.
static void shuffle(List<?> list, Random rnd)
Randomly permute the specified list using the specified source of randomness.
static <T extends Comparable<? super T>> void sort(List<T> list)
Sorts the specified list into ascending order, according to the natural ordering.
static <T> void sort(List<T> list, Comparator<? super T> c)
Sorts the specified list according to the order induced by the specified comparator.
static void swap(List<?> list, int i, int j)
Swaps the elements at the specified positions in the specified list.

G. Bruno Programmazione a oggetti 145


Map
A Map is an object that maps keys to values. A map cannot contain duplicate
keys: Each key can map to at most one value.
The JDK contains two new general-purpose Map implementations. HashMap,
which stores its entries in a hash table, is the best-performing implementation.
TreeMap, which stores its entries in a red-black tree, guarantees the order of
iteration.

G. Bruno Programmazione a oggetti 146


Interface Map<K,V>
static interface Map.Entry<K,V> A map entry (key-value pair).
void clear() Removes all of the mappings from this map.
boolean containsKey(Object key)
Returns true if this map contains a mapping for the specified key.
boolean containsValue(Object value)
Returns true if this map maps one or more keys to the specified
value.
Set<Map.Entry<K,V>> entrySet()
Returns a Set view of the mappings contained in this map.
boolean equals(Object o)
V get(Object key) Returns the value to which the specified key is mapped, or
null if this map contains no mapping for the key.
int hashCode()
boolean isEmpty() Returns true if this map contains no key-value mappings.
Set<K> keySet() Returns a Set view of the keys contained in this map.
V put(K key, V value) Associates the specified value with the specified key.

G. Bruno Programmazione a oggetti 147


Interface Map<K,V>
void putAll(Map<? extends K,? extends V> m)
Copies all of the mappings from the specified map to this map.
V remove(Object key)
Removes the mapping for a key from this map if it is present.
int size()
Returns the number of key-value mappings in this map.
Collection<V> values()
Returns a Collection view of the values contained in this map.

G. Bruno Programmazione a oggetti 148


Interface Map.Entry<K,V>
boolean equals(Object o)
Compares the specified object with this entry for equality.
K getKey()
Returns the key corresponding to this entry.
V getValue()
Returns the value corresponding to this entry.
int hashCode()
Returns the hash code value for this map entry.
V setValue(V value)
Replaces the value corresponding to this entry with the specified
value.

G. Bruno Programmazione a oggetti 149


Map
The Collection-view methods allow a Map to be viewed as a Collection in three
ways:
keySet: the Set of keys contained in the Map.
values: The Collection of values contained in the Map. This Collection is not a
Set, as multiple keys can map to the same value.
entrySet: The Set of key-value pairs contained in the Map. The Map interface
provides a small nested interface called Map.Entry that is the type of the
elements in this Set.

G. Bruno Programmazione a oggetti 150


Class HashMap<K,V>, Class TreeMap<K,V>
Costruttori
HashMap() Constructs an empty HashMap with the default initial capacity (16) and the
default load factor (0.75).
HashMap(int initialCapacity)
HashMap(int initialCapacity, float loadFactor)
HashMap(Map<? extends K,? extends V> m)
Constructs a new HashMap with the same mappings as the specified Map.
TreeMap() Constructs a new, empty tree map, using the natural ordering of its keys.
TreeMap(Comparator<? super K> comparator)
Constructs a new, empty tree map, ordered according to the given comparator.
TreeMap(Map<? extends K,? extends V> m)
Constructs a new tree map containing the same mappings as the given map,
ordered according to the natural ordering of its keys.
TreeMap(SortedMap<K,? extends V> m)
Constructs a new tree map containing the same mappings and using the
same ordering as the specified sorted map.

G. Bruno Programmazione a oggetti 151


Maps
For starters, suppose you want to know whether one Map is a submap of
another, that is, whether the first Map contains all of the key-value mappings in
the second. The following idiom does the trick:
if (m1.entrySet().containsAll(m2.entrySet())) { }
Along similar lines, suppose that you want to know if two Map objects contain
mappings for all the same keys:
if (m1.keySet().equals(m2.keySet())) { }
Suppose you want to remove all the key-value pairs that one Map has in common
with another:
m1.entrySet().removeAll(m2.entrySet());
Suppose you want to remove from one Map all the keys that have mappings in
another:
m1.keySet().removeAll(m2.keySet());

G. Bruno Programmazione a oggetti 152


Mappe
Esempio: conteggio di occorrenze di parole in un testo
package collezioni;
import java.util.*;
public class Collezioni4 {
public static void main(String[] args) {
String testo = "The poem was inspired by the sight of a field full of golden daffodils waving
in the wind";
String[] parole = testo.split(" "); System.out.println(Arrays.toString(parole));
Map<String, Parola> m = new TreeMap <String, Parola>();
for (String s: parole) {Parola p = m.get(s);
if (p == null) m.put(s, new Parola(s)); else p.incr();} System.out.println(m);
//{The=The:1, a=a:1, by=by:1, daffodils=daffodils:1, field=field:1, full=full:1,
golden=golden:1, // stampa per occorrenze decr
List<Parola> list = new ArrayList<Parola>(m.values());
Collections.sort(list);
System.out.println(list);
//[of:2, the:2, The:1, a:1, by:1, daffodils:1, field:1, full:1, golden:1, in:1, inspired:1, poem:1,
sight:1, was:1, waving:1, wind:1]

G. Bruno Programmazione a oggetti 153


Mappe
// senza distinzione tra maiuscole e minuscole
Comparator<String> comp = new Comparator<String>(){
public int compare(String s1, String s2) {return s1.compareToIgnoreCase(s2);}};
Map<String, Parola> m1 = new TreeMap <String, Parola>(comp);
for (String s: parole) {Parola p = m1.get(s);
if (p == null) m1.put(s, new Parola(s)); else p.incr();
}
list = new ArrayList<Parola>(m1.values());
Collections.sort(list);
System.out.println(list);
//[The:3, of:2, a:1, by:1, daffodils:1, field:1, full:1, golden:1, in:1, inspired:1,
poem:1, sight:1, was:1, waving:1, wind:1]
}
}

G. Bruno Programmazione a oggetti 154


class Parola
package collezioni;
public class Parola implements Comparable<Parola> {
private String p;
private int n = 1;
public Parola(String p) {this.p = p;}
public String toString(){return p + ":" + n;}
public int compareTo(Parola parola){
if (n > parola.n) return -1;
else if (n < parola.n) return 1;
else return p.compareTo(parola.p);
}
public void incr() {n++;}
}

G. Bruno Programmazione a oggetti 155


class ArrayMgr
package arrays;
import java.util.*;
public class ArrayMgr {
int sum(int[] v) {int r = 0; for (int i:v) r += i; return r;}
int lp(int[] v1, int[] v2) throws Exception {
if (v1.length != v2.length) throw new Exception ("invalid data");
int r = 0; for (int i = 0; i < v1.length; i++) {r += v1[i] * v2[i];} return r;}
int[][] vp(int[] v1, int[] v2) {
int[][] m = new int [v1.length][v2.length];
for (int i = 0; i < v1.length; i++)
for (int j = 0; j < v2.length; j++) m[i][j] = v1[i] * v2[j];
return m;
}

G. Bruno Programmazione a oggetti 156


class ArrayMgr
public static void main(String[] args) {
ArrayMgr a = new ArrayMgr();
int[] v1 = {2,3};
int[] v2 = {4,5};
System.out.println(Arrays.toString(v1)); //[2, 3]
System.out.println(a.sum(v1)); //5
try {
System.out.println(a.lp(v1, v2)); //23
}
catch (Exception e) {
System.out.println("exception: " + e.getMessage());
}
int[][] m = a.vp(v1, v2);
System.out.println(Arrays.deepToString(m)); //[[8, 10], [12, 15]]

G. Bruno Programmazione a oggetti 157


Utilities
Date, Calendar
Date()
Allocates a Date object and initializes it so that it represents the
time at which it was allocated, measured to the nearest millisecond.
Random
StringTokenizer

Uso di Random
Random randGen = new Random();
// intero casuale tra 0 e 99
int i = Math.abs(randGen.nextInt())%100;

G. Bruno Programmazione a oggetti 158


Calendar
import java.util.Calendar;
import java.util.GregorianCalendar;
public class GestioneDate {
public static void main(String[] args) {
Calendar c1 = new GregorianCalendar(); // oggi
Calendar c2 = new GregorianCalendar(2004,12,25);
// confronti con after e before
if (c1.after(c2)
System.out.println(c1.getTime()); //Wed Apr 21 17:58:08 CEST
2004

G. Bruno Programmazione a oggetti 159


Class Random
public class Random extends Object implements Serializable
An instance of this class is used to generate a stream of pseudorandom
numbers. The class uses a 48-bit seed, which is modified using a linear
congruential formula.
public Random()
Creates a new random number generator. Its seed is initialized to a
value based on the current time.
public Random(long seed)
Creates a new random number generator using a single long seed.
public float nextFloat()
Returns the next pseudorandom, uniformly distributed float value
between 0.0 and 1.0 from this random number generator's sequence.
public int nextInt()
Returns the next pseudorandom, uniformly distributed int value
from this random number generator's sequence.

G. Bruno Programmazione a oggetti 160


StringTokenizer
String CurrentLine = "a: b: c: d ";
StringTokenizer st = new StringTokenizer(CurrentLine,":",
false);
while (st.hasMoreTokens())
System.out.println(st.nextToken() + "|");

a|
b|
c| il token non contiene il
d | delimitatore

G. Bruno Programmazione a oggetti 161


StringTokenizer
public class StringTokenizer extends Object implements Enumeration
public StringTokenizer(String str, String delim, boolean returnTokens)
Constructs a string tokenizer for the specified string. The characters in the delim argument
are the delimiters for separating tokens. If the returnTokens flag is true, then the delimiter
characters are also returned as tokens. Each delimiter is returned as a string of length one.
If the flag is false, the delimiter characters are skipped and only serve as separators
between tokens.
public boolean hasMoreTokens() Tests if there are more tokens available from this tokenizer's
string.
public String nextToken() Returns the next token from this string tokenizer. Throws:
NoSuchElementException if there are no more tokens in this tokenizer's string.
public boolean hasMoreElements()
Returns the same value as the hasMoreTokens method. It exists so that this class can
implement the Enumeration interface.
public Object nextElement()
Returns the same value as the nextToken method, except that its declared return value is
Object rather than String. It exists so that this class can implement the Enumeration
interface. Throws: NoSuchElementException if there are no more tokens in this tokenizer's
string.
public int countTokens() Calculates the number of times that this tokenizer's nextToken
method can be called before it generates an exception.

G. Bruno Programmazione a oggetti 162


Scanner
public final class Scanner extends Object implements Iterator<String>
A simple text scanner which can parse primitive types and strings using regular
expressions.
A Scanner breaks its input into tokens using a delimiter pattern, which by default matches
whitespace. The resulting tokens may then be converted into values of different types
using the various next methods.
For example, this code allows a user to read a number from System.in:
Scanner sc = new Scanner(System.in); int i = sc.nextInt();
As another example, this code allows long types to be assigned from entries in a file
myNumbers:
Scanner sc = new Scanner(new File("myNumbers"));
while (sc.hasNextLong()) {long aLong = sc.nextLong();}
The scanner can also use delimiters other than whitespace. This example reads several
items in from a string:
String input = "1 fish 2 fish red fish blue fish";
Scanner s = new Scanner(input).useDelimiter("\\s*fish\\s*");
System.out.println(s.nextInt()); System.out.println(s.nextInt());
System.out.println(s.next()); System.out.println(s.next()); s.close();
prints the following output:
1
2
red
blue

G. Bruno Programmazione a oggetti 163


Enum
enum Season { WINTER, SPRING, SUMMER, FALL }

enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }

Suppose you want to add data and behavior to an enum. For example
consider the planets of the solar system. Each planet knows its mass and
radius, and can calculate its surface gravity and the weight of an object
on the planet. Here is how it looks:

EsempiParte1 pkg1 Planet

G. Bruno Programmazione a oggetti 164


enum Planet
package pkg1;
public enum Planet {
MERCURY (3.303e+23, 2.4397e6), VENUS (4.869e+24, 6.0518e6),
EARTH (5.976e+24, 6.37814e6), MARS (6.421e+23, 3.3972e6),
JUPITER (1.9e+27, 7.1492e7), SATURN (5.688e+26, 6.0268e7),
URANUS (8.686e+25, 2.5559e7), NEPTUNE (1.024e+26, 2.4746e7),
PLUTO (1.27e+22, 1.137e6);
private final double mass; // in kilograms
private final double radius; // in meters
Planet(double mass, double radius) {this.mass = mass; this.radius = radius;}
public double mass() { return mass; }
public double radius() { return radius; }
// universal gravitational constant (m3 kg-1 s-2)
public static final double G = 6.67300E-11;
public double surfaceGravity() {return G * mass / (radius * radius); }
public double surfaceWeight(double mass) {return mass * surfaceGravity();}}

G. Bruno Programmazione a oggetti 165


class TestPlanetEnum
package pkg1;
public class TestPlanetEnum {
public static void main(String[] args) {
double earthWeight = Double.parseDouble(args[0]);
double mass = earthWeight/Planet.EARTH.surfaceGravity();
for (Planet p : Planet.values())
System.out.printf("Your weight on %s is %.2f%n",
p, p.surfaceWeight(mass));
}
}

G. Bruno Programmazione a oggetti 166


Patterns
Reusable solutions to recurring problems

Architectural Patterns
An architectural pattern expresses a fundamental structural organization or
schema for software systems. It provides a set of predefined subsystems,
specifies their responsibilities, and includes rules and guidelines for
organizing the relationships between them.
Design Patterns
A design pattern provides a scheme for refining the subsystems or
components of a software system, or the relationships between them. It
describes commonly recurring structure of communicating components that
solves a general design problem within a particular context.
Idioms
An idiom is a low-level pattern specific to a programming language. An
idiom describes how to implement particular aspects of components or the
relationships between them using the features of the given language.

G. Bruno Programmazione a oggetti 167


Pattern publish/subscribe
Ci sono agenzie e abbonati; le agenzie pubblicano notizie generali o
notizie sportive e le inviano agli abbonati. Gli abbonati possono essere
persone o aziende e si abbonano alle agenzie.

<<interface>> <<interface>>
Agenzia Abbonato
void addAbbonato (Abbonato a); void riceviNotizia(Notizia nt);

G. Bruno Programmazione a oggetti 168


Modello UML
Ci sono agenzie e abbonati; le agenzie pubblicano notizie generali o notizie sportive e le
inviano agli abbonati. Gli abbonati possono essere persone o aziende e si abbonano alle
agenzie.
void addAbbonato (Abbonato a); void riceviNotizia(Notizia nt);

<<interface>> AgenziaStd <<interface>>


Agenzia Abbonato

Persona

Notizia

usage
Azienda
implementation NotiziaSportiva
inheritance

G. Bruno Programmazione a oggetti 169


Interfacce
package abbonamenti;
public interface Abbonato {
public void riceviNotizia(Notizia nt);
}

package abbonamenti;
public interface Agenzia {
void addAbbonato (Abbonato a);
}

G. Bruno Programmazione a oggetti 170


Notizie
package abbonamenti;
public class Notizia {
String contenuto;
protected String dettagli = "";
public Notizia(String contenuto) {this.contenuto = contenuto;}
public String toString() {return contenuto + " " + dettagli;}
}

package abbonamenti;
public class NotiziaSportiva extends Notizia {
public NotiziaSportiva(String contenuto, String dettagli) {
super(contenuto); this.dettagli = dettagli;}
}

G. Bruno Programmazione a oggetti 171


class AgenziaStd
package abbonamenti;
import java.util.*;
public class AgenziaStd implements Agenzia {
private String name;
private List<Abbonato> abbonati = new ArrayList<Abbonato>();
public AgenziaStd(String name) {this.name = name;}
public void addAbbonato(Abbonato a) {abbonati.add(a);}
public void pubblica(Notizia nt) {
for (Abbonato a: abbonati) a.riceviNotizia(nt);}
}

G. Bruno Programmazione a oggetti 172


Abbonati
package abbonamenti;
public class Persona implements Abbonato{
private String name;
public Persona(String name, Agenzia... agenzie) {
this.name = name; for (Agenzia a: agenzie) a.addAbbonato(this);
}
public void riceviNotizia(Notizia nt) {
System.out.println(getClass().getSimpleName() + " " + name + " ha ricevuto la
notizia " + nt);
}}

package abbonamenti;
public class Azienda extends Persona{
public Azienda(String name, Agenzia... agenzie) {
super(name, agenzie);
}}

G. Bruno Programmazione a oggetti 173


main
package abbonamenti;
public class TestAbbonamenti {
public static void main(String[] args) {
AgenziaStd quotidiano = new AgenziaStd("La gazzetta");
AgenziaStd qSportivo = new AgenziaStd("La gazzetta sportiva");
new Persona("mike", quotidiano, qSportivo);
new Azienda("ditta", quotidiano);
quotidiano.pubblica(new Notizia("Le borse ondeggiano"));
qSportivo.pubblica(new NotiziaSportiva("Nuovo record", "corsa 100 m"));
//Persona mike ha ricevuto la notizia Le borse ondeggiano
//Azienda ditta ha ricevuto la notizia Le borse ondeggiano
//Persona mike ha ricevuto la notizia Nuovo record corsa 100 m
}}

G. Bruno Programmazione a oggetti 174


Singleton pattern
Garantisce che di una classe esista ununica istanza.

G. Bruno Programmazione a oggetti 175


Singleton pattern
package audioclip;
public class AudioclipManager {
private static AudioclipManager instance = new AudioclipManager();
private Audioclip prevClip;
private AudioclipManager() { } // costruttore privato
public static AudioclipManager getInstance() {return instance;}
public void play(Audioclip clip) {
if (prevClip != null) prevClip.stop();
prevClip = clip; clip.play();}
public void stop() {
if (prevClip != null) {prevClip.stop(); prevClip = null;}}}
package audioclip;
public class Audioclip {
void play(){System.out.println("play");}
void stop(){System.out.println("stop");}}

G. Bruno Programmazione a oggetti 176


Uso
import audioclip.*;
public class TestAudioclip {
public static void main(String[] args) {
Audioclip a1 = new Audioclip();
Audioclip a2 = new Audioclip();
AudioclipManager m1 = AudioclipManager.getInstance();
// il costruttore non visibile
m1.play(a1); m1.play(a2); m1.stop();
}
}
play
stop
play
stop

G. Bruno Programmazione a oggetti 177


I/O
The concept of standard input and output streams is a C library concept
that has been assimilated into the Java environment. There are three
standard streams, all of which are managed by the java.lang.System
class:
Standard input--referenced by System.in
Used for program input, typically reads input entered by the user.
Standard output--referenced by System.out
Used for program output, typically displays information to the user.
Standard error--referenced by System.err
Used to display error messages to the user.

G. Bruno Programmazione a oggetti 178


FileNotFoundException Classi di IO
FileInputStream FileOutputStream I/O su file di blocchi di
byte
IOException I/O di tipi primitivi
readInt, readDouble,
DataInputStream DataOutputStream
readUTF
writeInt, writeDouble,
writeUTF

InputStreamReader OutputStreamWriter bridge tra byte e caratteri

IOException
readLine
BufferedReader PrintWriter caratteri - testo

FileReader FileWriter file di caratteri


FileNotFoundException IOException FileNotFoundException extends
IOException
G. Bruno Programmazione a oggetti 179
Binary File I/O
DataOutputStream out = new DataOutputStream(new
FileOutputStream("invoice1.bin"));

DataInputStream in = new DataInputStream(new


FileInputStream("invoice1.bin"));

Le classi FileOutputStream e FileInputStream sono usate


per l'apertura dei file; possono produrre eccezioni.

Le classi DataOutputStream e DataInputStream sono usate


per scrivere/leggere valori di tipi predefiniti.

G. Bruno Programmazione a oggetti 180


Esempi
Progetto EsempiFile

Scrittura e lettura di rettangoli


Es.
r0 60 2 1000 2000
r1 61 68 1000 2000
r2 4 99 1000 2000

G. Bruno Programmazione a oggetti 181


class Rettangolo
package pkg1;
import java.io.*;
public class Rettangolo {
int x, y, h, w; String n;
public Rettangolo(String n, int x, int y, int h, int w) {
this.x = x; this.y = y; this.h = h; this.w = w;
this.n = n;
}
public String toString() {
return ("" + n + " " + x + " " + y + " " + h + " " + w);
}
public void toBinFile(DataOutputStream out) throws IOException {
out.writeUTF(n); //UTF = Unicode Transformation Format
out.writeInt(x); out.writeInt(y); out.writeInt(h); out.writeInt(w);
}}

G. Bruno Programmazione a oggetti 182


TestClass
package test;
import java.util.*; import java.io.*; import pkg1.*;
public class TestClass {
int v(int k) {return (int) Math.round(Math.random() * k);}
ArrayList<Rettangolo> genList() {
ArrayList<Rettangolo> list = new ArrayList<Rettangolo>();
for (int i = 0; i < 3; i++)
list.add(new Rettangolo("r" + i, v(100), v(100), 1000, 2000));
return list;}
public static void main(String[] args) {
TestClass tc = new TestClass(); ArrayList<Rettangolo> list = tc.genList();
tc.txtFile("rettangoli.txt", list);
tc.binFile("rettangoli.bin", list);
tc.readText();}

G. Bruno Programmazione a oggetti 183


TestClass
void txtFile (String fileName, ArrayList<Rettangolo> list) {
try{
PrintWriter out = new PrintWriter(new FileWriter(fileName));
for(Rettangolo r: list) out.println(r); out.close();
BufferedReader in = new BufferedReader(new FileReader(fileName));
String line1 = in.readLine();
while (line1 != null) {
Scanner sc = new Scanner(line1);
String n = sc.next(); int x = sc.nextInt(); int y = sc.nextInt();
int h = sc.nextInt(); int w = sc.nextInt();
Rettangolo r1 = new Rettangolo(n, x, y, h, w);
System.out.println(r1);
line1 = in.readLine();
}
in.close();
}catch(IOException e){e.printStackTrace();}}

G. Bruno Programmazione a oggetti 184


TestClass
void binFile( String fileName, ArrayList<Rettangolo> list) {
try{
DataOutputStream out = new DataOutputStream(new
FileOutputStream(fileName));
for(Rettangolo r: list) r.toBinFile(out);
out.close();
DataInputStream in = new DataInputStream(new FileInputStream(fileName));
try {
while (true) {
String n = in.readUTF(); int x = in.readInt(); int y = in.readInt();
int h = in.readInt(); int w = in.readInt();
Rettangolo r1 = new Rettangolo(n, x, y, h, w); System.out.println(r1);
}
} catch (EOFException e) {}
in.close();
}catch(IOException e){e.printStackTrace();}}

G. Bruno Programmazione a oggetti 185


TestClass
void readText() {
try{
BufferedReader keyboard =
new BufferedReader(new InputStreamReader(System.in));
//read user's input
while (true) {
System.out.print("input text: ");
String line1 = keyboard.readLine();
System.out.println(line1.toUpperCase());
if (line1.equalsIgnoreCase("end")) break;
}
}catch(IOException e){
e.printStackTrace();}}

G. Bruno Programmazione a oggetti 186


Threads

G. Bruno Programmazione a oggetti 187


Threads
public class Thread extends Object implements Runnable
A thread is a thread of execution in a program. The Java Virtual Machine allows an
application to have multiple threads of execution running concurrently. Every thread
has a priority. Threads with higher priority are executed in preference to threads
with lower priority. Each thread may or may not also be marked as a daemon. When
code running in some thread creates a new Thread object, the new thread has its
priority initially set equal to the priority of the creating thread, and is a daemon
thread if and only if the creating thread is a daemon.
When a Java Virtual Machine starts up, there is usually a single non-daemon thread
(which typically calls the method named main of some designated class). The Java
Virtual Machine continues to execute threads until either of the following occurs:
The exit method of class Runtime has been called and the security manager has
permitted the exit operation to take place.
All threads that are not daemon threads have died, either by returning from the call
to the run method or by performing the stop method.
There are two ways to create a new thread of execution. One is to declare a class to be
a subclass of Thread. This subclass should override the run method of class Thread.
The other way to create a thread is to declare a class that implements the Runnable
interface.

G. Bruno Programmazione a oggetti 188


Scrittura dei Threads
1. Si definisce una sottoclasse di Thread e si scrive la logica nel metodo
run (che chiamato allo start del thread).
2. Se una classe implementa linterfaccia Runnable (ossia ha un metodo
run) si pu associare ad un thread un suo oggetto.
Class X implements Runnable { }
Runnable R = new X();
Thread T = new Thread(R);
T.start();
public interface Runnable {
public void run(); }
Definition: A thread
is a single sequential
flow of control within
a program.

G. Bruno Programmazione a oggetti 189


Stati

A thread becomes Not Runnable when one of these events occurs:


Its sleep method is invoked.
The thread calls the wait method to wait for a specific condition to
be satisifed.
The thread is blocking on I/O.
G. Bruno Programmazione a oggetti 190
SimpleThread
package threads; 0 Milano
public class SimpleThread extends Thread { 1 Torino
public SimpleThread(String name) { 2 Torino
super(name); 1 Milano
} 3 Torino
4 Torino
public void run() {
2 Milano
for (int i = 0; i < 10; i++) { 5 Torino
System.out.println(i + " " + getName()); 3 Milano
try { 6 Torino
sleep((long)(Math.random() * 1000)); 7 Torino
} catch (InterruptedException e) {} 4 Milano
} 8 Torino
System.out.println("DONE! " + getName()); 5 Milano
6 Milano
}
9 Torino
public static void main (String[] args) { 7 Milano
new SimpleThread("Torino").start(); 8 Milano
new SimpleThread("Milano").start(); DONE! Torino
}} 9 Milano
DONE! Milano

G. Bruno Programmazione a oggetti 191


Thread infinito
package threads;
public class SimpleThread1 extends Thread {
public SimpleThread1(String name) {super(name); }
public void run() {
int i = 0;
try {
while (true){
System.out.println(i++ + " " + getName());
sleep((long)(Math.random() * 1000));
}
} catch (InterruptedException e) {}
System.out.println("DONE! " + getName());}}

G. Bruno Programmazione a oggetti 192


TestSimpleThread1
input durata
package threads; in s: 2
import java.io.*; 0 Torino
public class TimerThread extends Thread{ 0 Milano
1 Milano
private int durata; private Thread[] threads; 1 Torino
public TimerThread(int durata, Thread... threads) { 2 Milano
super("timerThread"); this.durata = durata; 2 Torino
3 Milano
this.threads = threads;} 3 Torino
public void run() {for (Thread t: threads) t.start(); 4 Torino
try { 4 Milano
DONE!
sleep((long)(durata * 1000 )); Milano
} catch (InterruptedException e) {} DONE! Torino
for (Thread t: threads) t.interrupt();}
public static void main(String[] args) throws IOException, Exception {
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
System.out.print("input durata in s: ");
int durata = Integer.parseInt(keyboard.readLine());
TimerThread tt =new TimerThread(durata, new SimpleThread1("Torino"),
new SimpleThread1("Milano")); tt.start();}}

G. Bruno Programmazione a oggetti 193


Threads
A thread becomes Not Runnable when one of these events occurs:
Its sleep method is invoked.
The thread calls the wait method to wait for a specific condition to be
satisfied.
The thread is blocking on I/O.
Thread.sleep(1000);
Stopping a Thread
A thread arranges for its own death by having a run method that
terminates naturally.

G. Bruno Programmazione a oggetti 194


Sincronizzazioni
Esempio di produttori e consumatori che interagiscono tramite un buffer
circolare.
I produttori scrivono (aggiungono) dati; i consumatori leggono (tolgono)
dati.

Versione 1. Se il buffer pieno, il produttore non scrive. Se il buffer


vuoto, il consumatore non legge.

Versione 2. Se il buffer pieno, il produttore aspetta. Se il buffer vuoto,


il consumatore aspetta.

G. Bruno Programmazione a oggetti 195


class SimpleBuffer
package threads;
public class SimpleBuffer {
int size; private String[] b; int iw, ir;
protected int occupiedSlots = 0;
public SimpleBuffer (int size) {b = new String[size]; this.size = size;}
protected void write (String v) {b[iw] = v; iw = (iw + 1) % size; occupiedSlots++;}
protected String read () {
String v = b[ir]; ir = (ir + 1) % size; occupiedSlots--; return v;
}
public synchronized boolean put (Thread t, String v) throws
InterruptedException {
boolean res = occupiedSlots < size; if (res) write(v); return res;
}
public synchronized String get (Thread t) throws InterruptedException {
String res = null; if (occupiedSlots > 0) res = read();
return res;
}}

G. Bruno Programmazione a oggetti 196


Producer
package threads;
import java.util.*;
public class Producer extends Thread{
int interval; SimpleBuffer b; List<String> log = new
ArrayList<String>();
public Producer(String name, int interval, SimpleBuffer b) {
super(name); this.interval = interval; this.b = b;}
public void run() {
String[] text = "The early part of her life was spent in Paris".split(" ");
int i = 0;
try {
while (true){
if (b.put(this, text[i])) log.add(text[i]);
i = (i+1) % text.length;
long p = (long)(Math.random() * 1000 * interval);
sleep(p);
}
} catch (InterruptedException e) {}
System.out.println(getName() + " put " + log);}
}

G. Bruno Programmazione a oggetti 197


Consumer
package threads;
import java.util.*;
public class Consumer extends Thread{
int interval; SimpleBuffer b; List<String> log = new
ArrayList<String>();
public Consumer(String name, int interval, SimpleBuffer b) {
super(name); this.interval = interval; this.b = b;}
public void run() {
try {
while (true){
String s = b.get(this);
if (s != null) log.add(s);
long p = (long)(Math.random() * 1000 * interval);
sleep(p);
}
} catch (InterruptedException e) {}
System.out.println(getName() + " put " + log);}
}

G. Bruno Programmazione a oggetti 198


TestProdCons
package threads;
import java.io.*; import java.util.Scanner;
public class TestProdCons {
public static void main(String[] args) throws IOException, Exception {
BufferedReader keyboard = new BufferedReader(new
InputStreamReader(System.in));
System.out.print("input duration in s, size, producer rate, consumer rate,
buffer (S,Q): ");
String line = keyboard.readLine(); Scanner s = new Scanner(line);
int duration = s.nextInt(); int size = s.nextInt();
int pRate = s.nextInt(); int cRate = s.nextInt();
String bufferType = s.next(); SimpleBuffer b;
if (bufferType.equalsIgnoreCase("S")) b = new SimpleBuffer(size);
else b = new QBuffer(size);
Producer p1 = new Producer("p1", pRate, b);
Consumer c1 = new Consumer("c1", cRate, b);
Consumer c2 = new Consumer("c2", cRate, b);
TimerThread tt = new TimerThread(duration, p1, c1, c2);
tt.start();
}}

G. Bruno Programmazione a oggetti 199


Trace
input duration in s, size, producer rate, consumer rate, buffer (S,Q): 10 3 1 4 s
c1 put [early, her, spent]
p1 put [The, early, part, of, her, life, spent, early, of, her, spent]
c2 put [The, part, of, life, early]

G. Bruno Programmazione a oggetti 200


QBuffer
package threads;
public class QBuffer extends SimpleBuffer {
public QBuffer (int size) {super(size);}
public synchronized boolean put (Thread t, String v) throws
InterruptedException {
while (occupiedSlots == size) {
System.out.println(t.getName() + " waiting before putting " + v);
wait();
}
System.out.println(t.getName() + " put " + v); write(v);
notifyAll(); return true;
}
public synchronized String get (Thread t) throws InterruptedException {
while (occupiedSlots == 0) {
System.out.println(t.getName() + " waiting before getting ");
wait();
}
String res = read(); System.out.println(t.getName() +" got " + res);
notifyAll(); return res; }}

G. Bruno Programmazione a oggetti 201


Synchronized
Mentre un thread esegue un metodo synchronized di un oggetto, gli altri
thread che chiamano un metodo synchronized sullo stesso oggetto sono
bloccati.
Ogni oggetto ha un lock, chiamato monitor. Quando un thread chiama un
metodo synchronized di un oggetto il cui lock libero, il thread acquisisce
il lock (che diventa impegnato) ed esegue il metodo. Se invece il lock
impegnato si accoda.
Quando un metodo synchronized termina, il lock diventa libero e pu
essere acquisito da un eventuale thread in coda.
Una wait rilascia il lock e sospende il thread corrente, che verr poi
risvegliato da una notify o notifyAll eseguita da un altro thread. Il thread
risvegliato deve accertarsi che le condizioni di prosecuzione siano
verificate: in caso contrario chiama ancora la wait (di solito si usa un
loop).

G. Bruno Programmazione a oggetti 202


c2 got was
Trace p1 put Paris
c2 got spent
input duration in s, size, producer rate, p1 put The
consumer rate, buffer (S,Q): 10 3 1 4 q p1 waiting before putting early
c1 got in
c1 waiting before getting
p1 put The p1 put early
c1 got The p1 waiting before putting part
c2 waiting before getting c1 got Paris
p1 put early p1 put part
c2 got early c1 got The
p1 put part c2 got early
p1 put of p1 put of
c1 got part c2 got part
p1 put her
p1 put her
c2 got of
c2 got her p1 put life
p1 put life p1 waiting before putting was
p1 put was c1 put [The, part, life, in, Paris, The]
p1 put spent c2 put [early, of, her, was, spent, early, part]
c1 got life p1 put [The, early, part, of, her, life, was,
p1 put in spent, in, Paris, The, early, part, of, her, life]
p1 waiting before putting Paris

G. Bruno Programmazione a oggetti 203


awt e swing

Event-driven programming

G. Bruno Programmazione a oggetti 204


Swing
SwingApplication creates four commonly used Swing
components:
a frame, or main window (JFrame)
a panel, sometimes called a pane (JPanel)
a button (JButton)
a label (JLabel)

The frame is a top-level container. It exists mainly to provide a place for


other Swing components to paint themselves. The other commonly used top-
level containers are dialogs (JDialog) and applets (JApplet).
The panel is an intermediate container. Its only purpose is to simplify the
positioning of the button and label. Other intermediate Swing containers,
such as scroll panes (JScrollPane) and tabbed panes (JTabbedPane),
typically play a more visible, interactive role in a program's GUI.
The button and label are atomic components -- components that exist not to
hold random Swing components, but as self-sufficient entities that present
bits of information to the user. Often, atomic components also get input from
the user. The Swing API provides many atomic components, including combo
boxes (JComboBox), text fields (JTextField), and tables (JTable).

G. Bruno Programmazione a oggetti 205


Esempio

EsempiGUI ButtonDemo e ButtonDemo2

G. Bruno Programmazione a oggetti 206


ButtonDemo
package pkg1;
import javax.swing.*;import java.awt.*;import java.awt.event.*;
@SuppressWarnings("serial")
public class ButtonDemo extends JFrame implements ActionListener {
public static final int WIDTH = 300; public static final int HEIGHT = 100;
int val = 0; JLabel labelV;
public static void main(String[] args) {
ButtonDemo gui = new ButtonDemo();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); gui.setVisible(true);}
public ButtonDemo() {setSize(WIDTH, HEIGHT); setTitle("Demo");
Container contentPane = getContentPane();
contentPane.setBackground(Color.GRAY);
contentPane.setLayout(new FlowLayout());
JButton buttonP = new JButton("+"); buttonP.addActionListener(this);
contentPane.add(buttonP);
JButton buttonM = new JButton("-"); buttonM.addActionListener(this);
contentPane.add(buttonM);
labelV = new JLabel("0"); contentPane.add(labelV);}

G. Bruno Programmazione a oggetti 207


ButtonDemo
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("+"))
labelV.setText(String.valueOf(++val));
else if (e.getActionCommand().equals("-"))
labelV.setText(String.valueOf(--val));
}
}

G. Bruno Programmazione a oggetti 208


ButtonDemo1
package pkg1;
import javax.swing.*;import java.awt.*;import java.awt.event.*;
@SuppressWarnings("serial")
public class ButtonDemo1 extends JFrame {
public static final int WIDTH = 300; public static final int HEIGHT = 100;
int val = 0; JLabel labelV;
public static void main(String[] args) {
ButtonDemo1 gui = new ButtonDemo1();
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gui.setVisible(true);}
public ButtonDemo1(){setSize(WIDTH, HEIGHT); setTitle("Demo");
Container contentPane = getContentPane();
contentPane.setBackground(Color.GRAY);
contentPane.setLayout(new FlowLayout());
Listener l = new Listener();
JButton buttonP = new JButton("+");buttonP.addActionListener(l);
contentPane.add(buttonP);
JButton buttonM = new JButton("-");buttonM.addActionListener(l);
contentPane.add(buttonM);
labelV = new JLabel("0"); contentPane.add(labelV);}

G. Bruno Programmazione a oggetti 209


ButtonDemo1
private class Listener implements ActionListener {
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("+"))
labelV.setText(String.valueOf(++val));
else if (e.getActionCommand().equals("-"))
labelV.setText(String.valueOf(--val));
}
}
}

G. Bruno Programmazione a oggetti 210


Interface ActionListener
java.awt.event
Interface ActionListener
void actionPerformed(ActionEvent e) Invoked when an action occurs.

java.awt.event
Class ActionEvent
String getActionCommand()
Returns the command string associated with this action.
int getModifiers()
Returns the modifier keys held down during this action event.
long getWhen()
Returns the timestamp of when this event occurred.
String paramString()
Returns a parameter string identifying this action event.

G. Bruno Programmazione a oggetti 211


Layout principali

G. Bruno Programmazione a oggetti 212


Layout principali

Layout management is the process of determining the size and position of components.
By default, each container has a layout manager -- an object that performs layout
management for the components within the container. The Java platform supplies five
commonly used layout managers: BorderLayout, BoxLayout, FlowLayout,
GridBagLayout, and GridLayout.

G. Bruno Programmazione a oggetti 213


Event handling
Every time the user types a character or pushes a mouse button, an event occurs. Any
object can be notified of the event. All it has to do is implement the appropriate
interface and be registered as an event listener on the appropriate event source. Swing
components can generate many kinds of events.
Act that results in the event Listener type

User clicks a button, presses Return while typing in a text field, or chooses a menu item ActionListener

User closes a frame (main window) WindowListener

User presses a mouse button while the cursor is over a component MouseListener

User moves the mouse over a component MouseMotionListener

Component becomes visible ComponentListener

Component gets the keyboard focus FocusListener

Table or list selection changes ListSelectionListener

G. Bruno Programmazione a oggetti 214


Event handling
Each event is represented by an object that gives information about the event and
identifies the event source. Event sources are typically components, but other
kinds of objects can also be event sources. As the following figure shows, each
event source can have multiple listeners registered on it. Conversely, a single
listener can register with multiple event sources.

Caption: Multiple listeners can register to be


notified of events of a particular type from a
particular source.

G. Bruno Programmazione a oggetti 215


Event handling

Caption: When the user clicks a button, the button's action listeners are
notified.

Event-handling code executes in a single thread, the event-dispatching


thread. This ensures that each event handler will finish executing before the
next one executes. For instance, the actionPerformed method in the
preceding example executes in the event-dispatching thread. Painting code
also executes in the event-dispatching thread. This means that while the
actionPerformed method is executing, the program's GUI is frozen -- it won't
repaint or respond to mouse clicks, for example.

G. Bruno Programmazione a oggetti 216


Painting
When a Swing GUI needs to paint itself -- whether for the first time, in response to
becoming unhidden, or because it needs to reflect a change in the program's state -- it
starts with the highest component that needs to be repainted and works its way down the
containment hierarchy. This process is orchestrated by the AWT painting system, and made
more efficient and smooth by the Swing repaint manager and double-buffering code. In
this way, each component paints itself before any of the components it contains. This
ensures that the background of a JPanel, for example, is visible only where it isn't covered
by painting performed by one of the components it contains.
1. background 2. custom 3. border 4. children
(if opaque) painting (if any) (if any)
(if any)

G. Bruno Programmazione a oggetti 217


Previsioni
Si progetti uninterfaccia grafica che consenta linserimento di una serie
di temperature per varie citt; le temperature sono valori interi. Il
comando Clear cancella gli elementi gi inseriti; il comando All
visualizza lelenco ordinato per citt.
(1) Esempio di inserimento di una coppia citt temperatura (se
linserimento accettato appare added nellarea di testo). (2) Esempio di
risultato del comando All.

EsempiGUI Previsioni

G. Bruno Programmazione a oggetti 218


ListDemo

EsempiGUI ListDemo (esempio Sun rivisto)

G. Bruno Programmazione a oggetti 219


Applets

G. Bruno Programmazione a oggetti 220


Applets

Every applet is implemented by creating a subclass of the


Applet class. The following figure shows the inheritance
hierarchy of the Applet class. This hierarchy determines
much of what an applet can do and how, as you'll see on
the next few pages.

Panel is the simplest container class. A panel provides space in which an


application can attach any other component, including other panels. The
default layout manager for a panel is the FlowLayout layout manager.
A component is an object having a graphical representation that can be
displayed on the screen and that can interact with the user. Examples of
components are the buttons, checkboxes, and scrollbars of a typical graphical
user interface. The Component class is the abstract superclass of the nonmenu-
related Abstract Window Toolkit components.
G. Bruno Programmazione a oggetti 221
Applets

G. Bruno Programmazione a oggetti 222


SimpleApplet
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
public class SimpleApplet extends Applet{
String text = "I'm a simple applet";
public void init() {
setBackground(Color.cyan); }
public void start() {}
public void stop() {}
public void destroy() {}
public void paint(Graphics g){
//System.out.println("Paint");
g.setColor(Color.blue);
g.drawRect(0, 0, getSize().width -1, getSize().height -1);
g.setColor(Color.red);
g.drawString(text, 15, 25);
}
}

G. Bruno Programmazione a oggetti 223


SimpleApplet
To see the applet in action, you need an HTML file with the
Applet tag as follows:
<HTML>
<BODY>
<APPLET CODE=SimpleApplet.class WIDTH=200 HEIGHT=100>
</APPLET>
</BODY>
</HTML>

G. Bruno Programmazione a oggetti 224


SimpleApplet
The init Method: The init method is called when the applet is first
created and loaded by the underlying software.
The start Method: The start method is called when the applet is visited
such as when the end user goes to a web page with an applet on it. After
the start method executes, the event thread calls the paint method to
draw to the applet's Panel.
The stop and destroy Methods: The stop method stops the applet
when the applet is no longer on the screen such as when the end user
goes to another web page. The destroy method is called when the
browser exits.
The Graphics object passed to the paint method defines a graphics
context for drawing on the Panel. The Graphics object has methods for
graphical operations such as setting drawing colors, and drawing
graphics, images, and text.

G. Bruno Programmazione a oggetti 225


LineApplet1

Esempio
LineApplet1
LineThread
in EsempiGUI

G. Bruno Programmazione a oggetti 226


Mouse events
protected void processMouseEvent(MouseEvent e)
Processes mouse events occurring on this component by dispatching them to any registered
MouseListener objects.
This method is not called unless mouse events are enabled for this component. Mouse
events are enabled when one of the following occurs:
A MouseListener object is registered via addMouseListener.
Mouse events are enabled via enableEvents.

public synchronized void addMouseListener(MouseListener l)


Adds the specified mouse listener to receive mouse events from this component.

public interface MouseListener


mouseClicked(MouseEvent) Invoked when the mouse has been clicked on a component.
mouseEntered(MouseEvent) Invoked when the mouse enters a component.
mouseExited(MouseEvent) Invoked when the mouse exits a component.
mousePressed(MouseEvent) Invoked when a mouse button has been pressed on a
component.
mouseReleased(MouseEvent) Invoked when a mouse button has been released on a
component.
G. Bruno Programmazione a oggetti 227
SimpleJApplet
private class Listener implements ActionListener {
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().equals("+"))
labelV.setText(String.valueOf(++val));
else if (e.getActionCommand().equals("-"))
labelV.setText(String.valueOf(--val));
}
}
}

G. Bruno Programmazione a oggetti 253


Sviluppo di applicazioni java
per Android

G. Bruno Programmazione a oggetti 254


Android Development Tools
Android Development Tools (ADT) is a plugin
for the Eclipse IDE that is designed to give
you a powerful, integrated environment in
which to build Android applications.
ADT extends the capabilities of Eclipse to let
you quickly set up new Android projects,
create an application UI, add packages based
on the Android Framework API, debug your
applications using the Android SDK tools, and
even export signed (or unsigned) .apk files in
order to distribute your application.

From http://developer.android.com/training/

G. Bruno Programmazione a oggetti 255


Activity
An Activity is an application component that provides a screen with
which users can interact in order to do something, such as dial the
phone, take a photo, send an email, or view a map. Each activity is given
a window in which to draw its user interface.

All user interface elements in an Android app are built using View and
ViewGroup objects. A View is an object that draws something on the
screen that the user can interact with. A ViewGroup is an object that
holds other View (and ViewGroup) objects in order to define the layout of
the interface.

G. Bruno Programmazione a oggetti 256


Layout
A layout defines the visual structure for a user interface, such as the UI
for an activity or app widget. You can declare a layout in two ways:
Declare UI elements in XML. Android provides a straightforward
XML vocabulary that corresponds to the View classes and subclasses,
such as those for widgets and layouts.
Instantiate layout elements at runtime. Your application can create
View and ViewGroup objects (and manipulate their properties)
programmatically.

G. Bruno Programmazione a oggetti 257


Pagina

G. Bruno Programmazione a oggetti 258


ADT
Mapping view id, stringa

valore
pulsante +
pulsante Reset counter

Stringa id della view


valore zeroInt counterNumber
pulsante + buttonPlus buttonPlus
pulsante Reset counter buttonReset buttonReset

G. Bruno Programmazione a oggetti 260


public class CounterActivity extends SherlockActivity {
private TextView counter;
CounterActivity
public void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView (R.layout.counter);
counter = (TextView) findViewById(R.id.counterNumber);
Button plus = (Button) findViewById(R.id.buttonPlus);
plus.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String counterNumber = counter.getText().toString();
try {Integer number = Integer.parseInt(counterNumber);
number++; counter.setText(number.toString());
} catch (NumberFormatException exc) {counter.setText("0");}
}});
Button minus = (Button) findViewById(R.id.buttonMinus);
minus.setOnClickListener(new View.OnClickListener() {
come il precedente con number--;
G. Bruno Programmazione a oggetti 261
CounterActivity
Button reset = (Button) findViewById(R.id.buttonReset);
reset.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
counter.setText("0");
}
});

public static interface View.OnClickListener

G. Bruno Programmazione a oggetti 262


Esempi finali

Si trovano nel progetto EsempiFinali

classe faade
factory methods
strutture dati con mappe

progetto con UML

G. Bruno Programmazione a oggetti 263


UML
UML (Unified Modeling Language)
is a number of modeling languages/notations, not a global methodology.

Textbook on UML:
M. Fowler, UML distilled, Addison-Wesley.

OMG standard (UML 2.0): http://www.omg.org

Major kinds of diagrams


Structural: class, object, package / diagram
Behavioral: use case, activity, state, sequence / diagram

OCL (Object Constraint Language)

G. Bruno Programmazione a oggetti 264


Domain model
The system under consideration is made up of individuals called objects,
and objects belong to classes. There are systematic links between objects
and they are represented by links, called relationships, between their
classes.
Classes may have properties called attributes.
A domain model shows the classes, attributes and relationships.
An object model is a particular realization of a class model: it shows a
number of interrelated objects for illustrative purposes.

Domain model may also be called class models and information models.
Domain model: high level (conceptual, business) perspective
Class model: technical (implementation) perspective
Information model: data base perspective

G. Bruno Programmazione a oggetti 265


Example of domain model
In universities, there are professors and students; professors teach
courses and students are enrolled in courses.

Professor Course
teaches

enrolledIn

teaches: relationship name


(optional) Student

Two binary associative relationships; only binary relationships are


considered.

G. Bruno Programmazione a oggetti 266


Constraints
A course is taught by one professor. Professors teach 1..3 courses.
Students are enrolled in a number of courses. The minimum number of
enrollees in a course is 10; the maximum is 50.

1 1..3
Professor Course
teaches
+

enrolledIn
10..50

Student

G. Bruno Programmazione a oggetti 267


Multiplicity
How many associations a given object can be involved in?

1 1..3
Professor Course
Indicator Meaning
teaches
0..1 Zero or one

1 One only

0..*, * Zero or more

1..*, + One or more

n Only n (where n > 1)

0..n Zero to n (where n > 1)

m..n m to n (where n > m)

G. Bruno Programmazione a oggetti 268


Default multiplicity (*)

Book

1
Loan *

Book

1
Loan

G. Bruno Programmazione a oggetti 269


Composition
Objects can be made up of other objects.
When a compound object is deleted, all its components are automatically deleted.
A component exists only in connection with a container.

1 *
An order is made up of order
Product OrderLine lines; each order line refers to
+ a product and includes the
number of units required.

Order

Attributes:
OrderLine: int n.

G. Bruno Programmazione a oggetti 270


Inheritance
A vehicle has exactly one owner that may be a person or a company. A
vehicle may be a car or a motorcycle. Vehicle and Owner are abstract
classes (they cannot be instantiated).

class
{abstract} 1 {abstract}
model
Vehicle Owner

Car Motorcycle Person Company

car1 motorcycle1 car2


object
model
person1 company1
G. Bruno Programmazione a oggetti 271
Instances
Classes represent individuals, also called instances or objects.
An object model shows a number of objects along with their attributes
and associations.

Student

name = John Doe


id = ...

G. Bruno Programmazione a oggetti 272


Interpretations of class models

1. Programming-oriented perspective
The class model represents an object-oriented program (e.g. a java
program): the model classes are mapped to java classes, the attributes of
the model classes are mapped to the attributes of the java classes,
inheritance relationships are mapped to extend relationships between
java classes, and the other relationships are mapped to single references
or collections in the java classes.

G. Bruno Programmazione a oggetti 273


Tema n. 1
package test;
import competenze.*;
public class TestCompetenze {
public static void main(String[] args) {Competenze comp = new Competenze();
try{
comp.newCompetenza("java"); comp.newCompetenza("c++"); comp.newCompetenza("uml");
comp.newCompetenza("client-server"); comp.newCompetenza("er");
comp.newAttivit("codifica1", "java");
comp.newAttivit("sviluppo1", "uml", "client-server", "java");
comp.newUtente("analista1", "uml", "er"); comp.newUtente("sviluppatore1", "uml", "client-server", "java");
comp.newUtente("sviluppatore2", "uml", "client-server", "java", "c++");
System.out.println(comp.getAttivit("sviluppo1")); // sviluppo1[client-server, java, uml]
System.out.println(comp.getUtente("analista1")); // analista1[er, uml]
} catch (CompEccezione e){System.out.println(e.getMessage());}
System.out.println(comp.elencoCompetenzeRichieste());
// [java: nA=2 nU=2, client-server: nA=1 nU=2, uml: nA=1 nU=3, c++: nA=0 nU=1, er: nA=0 nU=1]
System.out.println(comp.elencoCompetenzePossedute());
// [uml: nA=1 nU=3, client-server: nA=1 nU=2, java: nA=2 nU=2, c++: nA=0 nU=1, er: nA=0 nU=1]
}}

G. Bruno Programmazione a oggetti 274


Tema n. 1
Si implementino le classi usate nel programma di test precedente; tali classi si
trovano nel package competenze.
Note
newCompetenza nomeCompetenza: genera un'eccezione se nomeCompetenza ripetuto;
newAttivit nomeAttivit, elenco competenze richieste: genera un'eccezione se
nomeAttivit ripetuto oppure se una competenza nell'elenco non stata
definita o ripetuta;
newUtente nomeUtente, elenco competenze possedute: genera un'eccezione come nel
caso precedente;
elencoCompetenzeRichieste: stampa l'elenco delle competenze ordinate in modo
decrescente in base al numero delle attivit richiedenti; a parit di n.
richiedenti vale lordine alfabetico delle competenze; si usi un oggetto
comparatore;
elencoCompetenzePossedute: stampa l'elenco delle competenze ordinate in base al
numero degli utenti possessori; stesse modalit del caso precedente;
getAttivit
getUtente

Suggerimento
In ogni oggetto Competenza si registrino il n. di attivit che la richiedono
e il n. di utenti che la possiedono.
Eccezioni: competenza ripetuta/inesistente, idem per attivit e utente

G. Bruno Programmazione a oggetti 275


Progetto
HM(nome) HM(nome)
Attivit Competenze Utente
toS toS

HM(nome)
associazione
HM = HashMap Competenza
toS

Attributi:
Competenza: String nome, int nA, int nU.
Attivit: String nome, TreeSet<String> competenze.
Utente: String nome, TreeSet<String> competenze.

toS: la classe ridefinisce il metodo toString.

G. Bruno Programmazione a oggetti 276


Competenza
package competenze;
public class Competenza {
private String nome;
private int nA = 0; private int nU = 0;
Competenza(String nome) {this.nome = nome;}
public String toString(){return nome + ":" + " nA=" + nA + " nU=" + nU;}
void incrNA() {nA++;}
void incrNU() {nU++;}

String getNome() {return nome;}


int getNA() {return nA;}
int getNU() {return nU;}
}

G. Bruno Programmazione a oggetti 277


Attivit e Utente
package competenze;
import java.util.*;
public class Attivit {
private String nome; private TreeSet<String> competenze;
Attivit(String nome, TreeSet<String> competenze) {
this.nome = nome; this.competenze = competenze;}
public String toString(){return nome + competenze;}}

package competenze;
import java.util.*;
public class Utente {
private String nome; private TreeSet<String> competenze;
Utente(String nome, TreeSet<String> competenze) {
this.nome = nome; this.competenze = competenze;}
public String toString(){return nome + competenze;}}

G. Bruno Programmazione a oggetti 278


CompEccezione
package competenze;
@SuppressWarnings("serial")
public class CompEccezione extends Exception {
public CompEccezione(String s) {super(s);}}

G. Bruno Programmazione a oggetti 279


Competenze
package competenze;
import java.util.*;
public class Competenze {
private Map<String,Competenza> competenze = new HashMap<String,Competenza>();
private Map<String,Attivit> attivit = new HashMap<String,Attivit>();
private Map<String,Utente> utenti = new HashMap<String,Utente>();

public void newCompetenza (String nome) throws CompEccezione {


if (competenze.containsKey(nome))
throw new CompEccezione("competenza duplicata:" + nome);
Competenza c = new Competenza(nome);
competenze.put(nome, c);}

G. Bruno Programmazione a oggetti 280


Competenze
public void newAttivit (String nome, String... v) throws CompEccezione {
TreeSet<String> s = new TreeSet<String>();
if (attivit.containsKey(nome)) throw new CompEccezione("attivit duplicata:" + nome);
for (String c:v){
if (competenze.get(c) == null) throw
new CompEccezione("competenza inesistente:" + c);
else if (!s.add(c)) throw new CompEccezione("competenza duplicata:" + c);
}
for (String c:v) {competenze.get(c).incrNA();}
Attivit a = new Attivit(nome, s); attivit.put(nome, a);}

G. Bruno Programmazione a oggetti 281


Competenze
public void newUtente (String nome, String... v) throws CompEccezione {
TreeSet<String> s = new TreeSet<String>();
if (utenti.containsKey(nome)) throw new CompEccezione("utente duplicato:" + nome);
for (String c:v)
{if (competenze.get(c) == null) throw new CompEccezione("competenza inesistente:" + c);
else if (!s.add(c)) throw new CompEccezione("competenza duplicata:" + c);}
for (String c:v){competenze.get(c).incrNU();}
Utente u = new Utente(nome, s); utenti.put(nome, u);}

public Attivit getAttivit (String nome) throws CompEccezione {


Attivit a = attivit.get(nome);
if(a == null) throw new CompEccezione("attivit inesistente:" + nome);
else return a;}

public Utente getUtente (String nome) throws CompEccezione {


Utente u = utenti.get(nome);
if(u == null) throw new CompEccezione("utente inesistente:" + nome);
else return u;}

G. Bruno Programmazione a oggetti 282


Competenze
public String elencoCompetenzeRichieste () {
Comparator<Competenza> comparator = new Comparator<Competenza>() {
public int compare (Competenza c1, Competenza c2) {
if (c2.getNA() == c1.getNA()) return c1.getNome().compareTo(c2.getNome());
if (c2.getNA() > c1.getNA()) return 1; else return -1; }};
List<Competenza> l1 = new ArrayList<Competenza>(competenze.values());
Collections.sort (l1, comparator); return l1.toString();}

public String elencoCompetenzePossedute () {


Comparator<Competenza> comparator = new Comparator<Competenza>() {
public int compare (Competenza c1, Competenza c2) {
if (c2.getNU() == c1.getNU()) return c1.getNome().compareTo(c2.getNome());
if (c2.getNU() > c1.getNU()) return 1; else return -1;}};
List<Competenza> l1 = new ArrayList<Competenza>(competenze.values());
Collections.sort (l1, comparator); return l1.toString();}
}

G. Bruno Programmazione a oggetti 283


Variante
Data una competenza elencare le attivit o gli utenti interessati.

G. Bruno Programmazione a oggetti 284


TestCompetenze1
package test; import competenze1.*;
public class TestCompetenze1 {
public static void main(String[] args) {Competenze comp = new Competenze();
try{
comp.newCompetenza("java"); comp.newCompetenza("c++");
comp.newCompetenza("uml");comp.newCompetenza("client-server");
comp.newCompetenza("er");comp.newAttivit("codifica1", "java");
comp.newAttivit("sviluppo1", "uml", "client-server", "java");
comp.newUtente("analista1", "uml", "er");
comp.newUtente("sviluppatore1", "uml", "client-server", "java");
comp.newUtente("sviluppatore2", "uml", "client-server", "java", "c++");
System.out.println(comp.getAttivit("sviluppo1").getInfo()); // sviluppo1[client-server,
java, uml]
System.out.println(comp.getUtente("analista1").getInfo()); // analista1[er, uml]
System.out.println(comp.getCompetenza("java").getAttivit());
// attivit che richiedono java [codifica1, sviluppo1]
System.out.println(comp.getCompetenza("java").getUtenti());
// utenti che possiedono java [sviluppatore1, sviluppatore2]
} catch (CompEccezione e){System.out.println(e.getMessage());}
System.out.println(comp.elencoCompetenzeRichieste());
// [java: nA=2 nU=2, client-server: nA=1 nU=2, uml: nA=1 nU=3, c++: nA=0 nU=1, er:
nA=0 nU=1]}}

G. Bruno Programmazione a oggetti 285


Progetto
HM(nome) HM(nome)
Attivit Competenze Utente
toS toS
TS TS
HM(nome)

Competenza
TS TS
toS
HM = HashMap
TS = TreeSet

Attributi: associazione
Competenza: String nome.
Attivit: String nome. associazione bidirezionale m,n
Utente: String nome.

toS: la classe ridefinisce il metodo toString.

G. Bruno Programmazione a oggetti 286


Competenze
package competenze1;

import java.util.*;
public class Competenze {
private Map<String,Competenza> competenze = new HashMap<String,Competenza>();
private Map<String,Attivit> attivit = new HashMap<String,Attivit>();
private Map<String,Utente> utenti = new HashMap<String,Utente>();
public void newCompetenza (String nome) throws CompEccezione {
if (competenze.containsKey(nome)) throw new CompEccezione("competenza duplicata:" + nome);
Competenza c = new Competenza(nome); competenze.put(nome, c);}
privateTreeSet<Competenza> getCompetenze (String[] v) throws CompEccezione {
TreeSet<Competenza> s = new TreeSet<Competenza>();
for (String c:v){
Competenza comp = competenze.get(c);
if (comp == null) throw new CompEccezione("competenza inesistente:" + c);
else if (!s.add(comp)) throw new CompEccezione("competenza duplicata:" + c);
}
return s;}
public void newAttivit (String nome, String... v) throws CompEccezione {
if (attivit.containsKey(nome)) throw new CompEccezione("attivit duplicata:" + nome);
Attivit a = new Attivit(nome); attivit.put(nome, a);
for (Competenza c: getCompetenze (v)) {a.addCompetenza(c); c.addAttivit(a);}
}

G. Bruno Programmazione a oggetti 287


Competenza
package competenze1;
import java.util.*;
public class Competenza implements Comparable<Competenza> {
private String nome;
private TreeSet<Attivit> attivit = new TreeSet<Attivit>();
private TreeSet<Utente> utenti = new TreeSet<Utente>();
Competenza (String nome) {this.nome = nome;}
public String toString (){return nome + ":" + " nA=" + attivit.size() + " nU=" + utenti.size();}
String getNome() {return nome;}
public int compareTo(Competenza c) {return nome.compareTo(c.nome);}
void addAttivit (Attivit a){attivit.add(a);}
void addUtente (Utente u){utenti.add(u);}
public int getNA() {return attivit.size();}
public int getNU() {return utenti.size();}
public String getAttivit(){return "attivit che richiedono " + nome + " " + attivit.toString();}
public String getUtenti(){return "utenti che possiedono " + nome + " " + utenti.toString();}
}

G. Bruno Programmazione a oggetti 288


Attivit
package competenze1;
import java.util.*;
public class Attivit implements Comparable<Attivit> {
private String nome;
private TreeSet<Competenza> competenze = new TreeSet<Competenza>();
Attivit (String nome) {this.nome = nome;}
void addCompetenza (Competenza c){competenze.add(c);}
public String toString(){return nome;}
public String getInfo(){
TreeSet<String> s = new TreeSet<String>();
for (Competenza c: competenze) s.add(c.getNome());
return nome + s;}
public int compareTo (Attivit a) {return nome.compareTo(a.nome);}
}

G. Bruno Programmazione a oggetti 289


package test;
import newBiblioteca.*;
Tema n. 2
public class TestPrestiti {
@SuppressWarnings("unused")
public static void main(String[] args) {
Biblioteca bib = new Biblioteca();
try{bib.newLibro("titolo1", 1); bib.newLibro("titolo2", 2); bib.newLibro("titolo3", 3);
Utente u1 = bib.newUtente("utente1", 1); bib.newUtente("utente2", 3);
int c1 = bib.newPrestito("utente1", "titolo1"); bib.restituzione("utente1", c1);
int c2 = bib.newPrestito("utente1", "titolo3");
int c3 = bib.newPrestito("utente2", "titolo2");
int c4 = bib.newPrestito("utente2", "titolo1");
System.out.println("prestiti di u1 " + u1.getPrestiti());
}catch(BiblioEccezione e){System.out.println(e.getMessage());}
System.out.println(bib.graduatoriaLibri());
System.out.println(bib.prestitiInCorso());}
}
prestiti di u1 [titolo3:103(utente1)]
[titolo1:2, titolo2:1, titolo3:1]
[titolo1:100(utente2), titolo2:101(utente2), titolo3:103(utente1)]

G. Bruno Programmazione a oggetti 290


Tema n. 2
Si implementino le classi usate nel programma di test precedente; tali classi si
trovano nel package biblioteca. Tutti gli attributi di tali classi devono essere privati.
newLibro titolo, nVolumi: genera nVolumi disponibili per il libro dal titolo dato;
produce uneccezione se titolo null oppure ripetuto o nVolumi <= 0. Ogni volume
ha un numero progressivo univoco a partire da 100.
newUtente nome, maxVolumi: genera un utente con il nome dato e stabilisce il n.
max di volumi che pu prendere in prestito simultaneamente; produce uneccezione se
nome null oppure ripetuto o maxVolumi <= 0.
newPrestito utente, titolo: genera un prestito e fornisce il codice del volume; produce
uneccezione se utente/titolo null oppure non esiste o lutente ha raggiunto il max
numero di libri in prestito o non c alcun volume disponibile.
restituzione utente, codice; restituisce il volume con il codice dato; produce
uneccezione se utente null oppure non esiste o il codice non si riferisce ad un
volume preso in prestito dallutente.
graduatoriaLibri fornisce lelenco dei libri ordinati in base al n. dei prestiti totali e
a parit di tale numero in base al titolo; si usi un comparator.
prestitiInCorso fornisce lelenco dei prestiti in corso ordinati in base al titolo e al
codice del volume.

G. Bruno Programmazione a oggetti 291


Progetto
HM(titolo) HM(nome)
Libro Biblioteca Utente
toS 1 1

array[libro. nVolumi] HM(codice)


prestiti
Volume
toS TS
HM = HashMap
TS = TreeSet

Attributi
Libro: String titolo, int nVolumi, int nPrestiti.
Volume: int codice, Libro libro.
Utente: String nome, int maxVolumi.

G. Bruno Programmazione a oggetti 292


Biblioteca
package newBiblioteca;
import java.util.*;
public class Biblioteca {
private Map<String,Libro> libri = new HashMap<String,Libro>();
private Map<String,Utente> utenti = new HashMap<String,Utente>();
private Map<Integer,Volume> prestiti = new HashMap<Integer,Volume>();
private int nuovoCodice = 100;
public Libro newLibro (String titolo, int nVolumi) throws BiblioEccezione {
if (titolo == null || nVolumi <= 0) throw new BiblioEccezione
("newLibro: dati errati - " + titolo + " " + nVolumi);
if (libri.containsKey(titolo)) throw new BiblioEccezione
("newLibro: libro duplicato - " + titolo);
Libro l = new Libro(titolo, nVolumi, nuovoCodice); nuovoCodice += nVolumi;
libri.put(titolo, l); return l;}
public Utente newUtente (String nome, int maxVolumi) throws BiblioEccezione {
if (nome == null || maxVolumi <= 0) throw new BiblioEccezione
("newUtente: dati errati - " + nome + " " + maxVolumi);
if (utenti.containsKey(nome)) throw new BiblioEccezione
("newUtente: utente duplicato - " + nome);
Utente u = new Utente(nome, maxVolumi);utenti.put(nome, u); return u;}

G. Bruno Programmazione a oggetti 293


Biblioteca
public int newPrestito( String utente, String titolo) throws BiblioEccezione {
if (titolo == null || utente == null) throw new BiblioEccezione ("newPrestito: dati errati - " + titolo + " " + utente);
Utente u = utenti.get(utente);
if (u == null) throw new BiblioEccezione ("newPrestito: utente non definito - " + utente);
if (!u.prestitoAmmissibile()) throw new BiblioEccezione ("newPrestito: max prestiti per " + utente);
Libro l = libri.get(titolo); if (l == null) throw new BiblioEccezione ("newPrestito: dati errati - " + titolo);
Volume v = l.getVolume();
if (v == null) throw new BiblioEccezione ("newPrestito: volume non disponibile - " + titolo);
u.addVolume(v); v.setUtente(u); int c = v.getCodice(); prestiti.put(c, v);
return c;}
public void restituzione (String utente, int codice) throws BiblioEccezione {
Utente u = utenti.get(utente);
if (u == null) throw new BiblioEccezione ("restituzione: dati errati - " + utente);
Volume v = prestiti.get(codice);
if (v == null || u != v.getUtente())
throw new BiblioEccezione ("restituzione: dati errati");
v.clearUtente(); u.removeVolume(v); prestiti.remove(codice);

G. Bruno Programmazione a oggetti 294


Biblioteca
public String graduatoriaLibri() {
Comparator<Libro> ordine = new Comparator<Libro>() {
public int compare(Libro l1, Libro l2) {
if (l2.getNPrestiti() == l1.getNPrestiti())
return l1.getTitolo().compareTo(l2.getTitolo());
if (l2.getNPrestiti() > l1.getNPrestiti()) return 1;
else return -1;
}};
List<Libro> list1 = new ArrayList<Libro>(libri.values());
Collections.sort(list1, ordine); return list1.toString();}

public String prestitiInCorso(){


List<Volume> list1 = new ArrayList<Volume>(prestiti.values());
Collections.sort(list1); return list1.toString();}

G. Bruno Programmazione a oggetti 295


Libro
package newBiblioteca;
public class Libro {
private String titolo; private int nPrestiti = 0;
private Volume[] volumi;
Libro (String titolo, int n, int nuovoCodice){
this.titolo = titolo; volumi = new Volume[n];
for (int i = 0; i < volumi.length; i++)
volumi[i] = new Volume(this, nuovoCodice++);
}
String getTitolo (){return titolo;}
int getNPrestiti () {return nPrestiti;}
Volume getVolume() {
for (int i = 0; i < volumi.length; i++){
Volume v = volumi[i];
if (v.getDisp()) {nPrestiti ++; return v;}
}
return null;}
public String toString(){return titolo + ":" + nPrestiti;}}

G. Bruno Programmazione a oggetti 296


package newBiblioteca; Volume
public class Volume implements Comparable<Volume> {
private int codice; private Libro libro; private Utente utente = null;
Volume(Libro l, int nuovoCodice){libro = l; codice = nuovoCodice;}
void setUtente(Utente u) {utente = u;}
void clearUtente() {utente = null;}
boolean getDisp () {return utente == null;}
int getCodice(){return codice;}
Libro getLibro() {return libro;}
Utente getUtente() {return utente;}
public int compareTo(Volume v) {
if (codice == v.codice) return 0;
int r = getLibro().getTitolo().compareTo(v.getLibro().getTitolo());
if (r == 0) if (codice > v.codice) r = 1; else r = -1;
return r;}
public String toString(){return getLibro().getTitolo() + ":" + codice
+ "(" + utente.getNome() + ")";}}

G. Bruno Programmazione a oggetti 297


Utente
package newBiblioteca;
import java.util.*;
public class Utente {
private String nome; private int maxVolumi;
private TreeSet<Volume> volumi = new TreeSet<Volume>();
Utente(String nome, int maxVolumi)
{this.nome = nome; this.maxVolumi = maxVolumi;}
String getNome(){return nome;}
boolean prestitoAmmissibile () {return volumi.size() < maxVolumi;}
void addVolume(Volume v) {volumi.add(v);}
void removeVolume(Volume v) {volumi.remove(v);}

// aggiunto per la stampa dei prestiti


public TreeSet<Volume> getPrestiti() {return volumi;}
}

G. Bruno Programmazione a oggetti 298


BiblioEccezione
package newBiblioteca;
@SuppressWarnings("serial")
public class BiblioEccezione extends Exception {
BiblioEccezione(String s) {super(s);}}

G. Bruno Programmazione a oggetti 299


GUI

Si progetti uninterfaccia grafica (attributi e metodo actionPerformed della


classe GUI) che consenta luso del package di cui al punto 1. I pulsanti
corrispondono alle operazioni definite al punto 1.
Ad esempio, detti t1 e t2 i valori inseriti nelle due caselle di testo, newLibro
inserisce il libro con titolo t1 e con n. volumi pari a t2.
Eventuali eccezioni sono mostrate nellarea di testo. Larea di testo mostra la
conferma done nel caso di newLibro, newUtente e restituzione se loperazione
andata a buon fine, il codice del prestito nel caso di newPrestito, il risultato della
query negli altri casi. La figura precedente presenta il risultato di
graduatoriaLibri.

G. Bruno Programmazione a oggetti 300


GUI

private JTextArea ta;


private JTextField tf1; private JTextField tf2;
private Biblioteca bib = new Biblioteca();

public static final String LIBRO = "newLibro";


public static final String UTENTE = "newUtente";
public static final String PRESTITO = "newPrestito";
public static final String RESTITUZIONE = "restituzione";
public static final String INCORSO = "prestitiInCorso";
public static final String GRAD = "graduatoriaLibri";

G. Bruno Programmazione a oggetti 301


actionPerformed
public void actionPerformed(ActionEvent e) {
String actionCommand = e.getActionCommand();
ta.setText(""); String s1 = tf1.getText(); String s2 = tf2.getText();
try{ if (actionCommand.equals(LIBRO)){
bib.newLibro(s1, Integer.parseInt(s2)); ta.setText("done");}
else if (actionCommand.equals(UTENTE)) {
bib.newUtente(s1, Integer.parseInt(s2)); ta.setText("done");}
else if (actionCommand.equals(PRESTITO)) {
ta.setText(bib.newPrestito(s1, s2) + "");}
else if (actionCommand.equals(RESTITUZIONE)) {
bib.restituzione(s1, Integer.parseInt(s2));
ta.setText("done");}
else if (actionCommand.equals(GRAD)) {
ta.setText(bib.graduatoriaLibri());}
else if (actionCommand.equals(INCORSO)) {
ta.setText(bib.prestitiInCorso());}
}catch(BiblioEccezione ex){ta.setText(ex.getMessage());}
catch(NumberFormatException ex){ta.setText(ex.getMessage());}
}

G. Bruno Programmazione a oggetti 302


Tema n. 3
import voli.*;
public class TestVoli {
public static void main(String[] args) {
try{ Voli vi = new Voli();
Aereo a1 = vi.addAereo("a1", "aereo a1", 100);
Aereo a2 = vi.addAereo("a2", "aereo a2", 150);
vi.addVolo("v1", "a1", "L1", 8, "L2", 10);
vi.addVolo("v10", "a1", "L23", 6, "L34", 7);
vi.addVolo("v2", "a2", "L3", 12, "L4", 14);
//vi.addVolo("v20", "a1", "L5", 9, "L6", 11); volo sovrapposto
vi.addPrenotazione("v1", "pass5", 1);
vi.addPrenotazione("v1", "pass2", 1);
//vi.addPrenotazione("v1", "pass2", 1); prenotazione duplicata
VoloGiornaliero vg = vi.getVoloGiornaliero("v1", 1);
System.out.println(vg); // 1 v1 da L1:8 a L2:10[pass2, pass5]
System.out.println(a1);
// a1 aereo a1 100 [v10 da L23:6 a L34:7, v1 da L1:8 a L2:10]
}catch(VoliEx e){System.out.println(e);}}}

G. Bruno Programmazione a oggetti 303


Tema n. 3
Il programma riguarda la gestione delle prenotazioni di voli giornalieri nellambito di una
settimana.
addAereo codiceAereo, descrizione, numeroPosti
genera un aereo e produce un'eccezione se codiceAereo null o ripetuto o se numeroPosti <
0.
addVolo codiceVolo, codiceAereo, luogoPartenza, oraPartenza, luogoArrivo, oraArrivo
produce un'eccezione se codiceVolo null o ripetuto o se laereo non esiste, se i luoghi sono
nulli e le ore non sono comprese tra 1 e 24 e oraArrivo non maggiore di oraPartenza;
inoltre produce uneccezione se tale volo si sovrappone ad un altro volo per lo stesso aereo
(detti v1 e v2 due voli per lo stesso aereo, non si ha sovrapposizione se
v1.oraArrivo < v2.oraPartenza o v1.oraPartenza > v2.oraArrivo.
Genera il volo in base al suggerimento seguente: conviene che un oggetto volo, che
stabilisce lorario di un volo, contenga un array di 7 voli giornalieri, perch le prenotazioni
si riferiscono ai voli giornalieri.
addPrenotazione codiceVolo, passeggero, giorno
produce un'eccezione se il volo non esiste, passeggero nullo o giorno non compreso tra 1
e 7 e inoltre se non vi sono posti disponibili sul volo giornaliero nel giorno indicato o la
prenotazione duplicata; aggiunge il passeggero alle prenotazioni del volo giornaliero nel
giorno indicato.

G. Bruno Programmazione a oggetti 304


Voli Progetto
HM(codiceVolo) HM(codiceAereo)
TS 1
Volo Aereo
C
toS 1 toS
TS = TreeSet
[7] HM = HashMap
Volo
toS Giornaliero

Attributi
Aereo: String codiceAereo, String descrizione, int numeroPosti.
Volo: String codiceVolo, String luogoPartenza, String luogoArrivo, int
oraPartenza, int oraArrivo.
VoloGiornaliero: int giorno, TreeSet(String) prenotazioni.

G. Bruno Programmazione a oggetti 305


package voli; import java.util.*;
Voli
public class Voli {
private Map<String, Aereo> aerei = new HashMap<String, Aereo>();
private Map<String, Volo> voli = new HashMap<String, Volo>();
public Aereo addAereo (String codiceAereo, String descrizione, int numeroPosti) throws VoliEx{
if (codiceAereo == null || numeroPosti <= 0 || aerei.containsKey(codiceAereo))
throw new VoliEx("dati errati in addAereo: " + codiceAereo);
Aereo a1 = new Aereo(codiceAereo, descrizione, numeroPosti);
aerei.put(codiceAereo, a1); return a1;}
public void addVolo (String codiceVolo, String codiceAereo, String luogoPartenza, int
oraPartenza, String luogoArrivo, int oraArrivo) throws VoliEx {
if (codiceVolo == null || voli.containsKey(codiceVolo) || luogoPartenza == null || luogoArrivo == null
|| oraPartenza < 1 || oraPartenza > 24 || oraArrivo < 1 || oraArrivo > 24 || oraPartenza >= oraArrivo
|| !aerei.containsKey(codiceAereo)) throw new VoliEx("dati errati in addVolo: " + codiceVolo);
Aereo a = aerei.get(codiceAereo);
Volo v1 = new Volo(codiceVolo, a, luogoPartenza, oraPartenza, luogoArrivo, oraArrivo);
a.addVolo(v1);//verifica sovrapposizione voli su aereo
voli.put(codiceVolo, v1);
}

G. Bruno Programmazione a oggetti 306


Voli
public void addPrenotazione (String codiceVolo, String passeggero, int giorno)
throws VoliEx {
getVoloGiornaliero(codiceVolo, giorno).addPrenotazione(passeggero);
}

public VoloGiornaliero getVoloGiornaliero(String codiceVolo, int giorno)


throws VoliEx {
if (codiceVolo == null || giorno < 1 || giorno > 7 || !voli.containsKey(codiceVolo)) throw
new VoliEx("dati errati in getVoloGiornaliero: " + codiceVolo);
Volo v1 = voli.get(codiceVolo);
return v1.getVoloGiornaliero(giorno);
}}

G. Bruno Programmazione a oggetti 307


Aereo
package voli;
import java.util.*;
public class Aereo {
private String codiceAereo; private String descrizione;
private int numeroPosti;
private TreeSet<Volo> voli = new TreeSet<Volo>();
Aereo(String codiceAereo, String descrizione, int numeroPosti){
this.codiceAereo = codiceAereo;
this.descrizione = descrizione;
this.numeroPosti = numeroPosti;}
int getNumeroPosti() { return numeroPosti;}
void addVolo(Volo volo) throws VoliEx{
if (!voli.add(volo)) throw new VoliEx("sovrapposizione voli:" + volo.getCodiceVolo());
}
public String toString(){
return codiceAereo + " " + descrizione + " " + numeroPosti + " " + voli;}
}

G. Bruno Programmazione a oggetti 308


package voli; Volo
public class Volo implements Comparable<Volo> {
private String codiceVolo;
private String luogoPartenza; private String luogoArrivo;
private int oraPartenza; private int oraArrivo;
private Aereo aereo; private VoloGiornaliero[] voliGiornalieri;
String getCodiceVolo() {return codiceVolo;} Aereo getAereo() {return aereo;}
Volo(String codiceVolo, Aereo aereo, String luogoPartenza, int oraPartenza, String
luogoArrivo, int oraArrivo){ this.codiceVolo = codiceVolo; this.aereo = aereo;
this.luogoPartenza = luogoPartenza; this.oraPartenza = oraPartenza;
this.luogoArrivo = luogoArrivo; this.oraArrivo = oraArrivo;
voliGiornalieri = new VoloGiornaliero[7];
for (int g = 0; g < 7; g++) voliGiornalieri[g] = new VoloGiornaliero(this, g);}
public int compareTo(Volo v2){if (this.oraArrivo < v2.oraPartenza) return -1;
else if (this.oraPartenza > v2.oraArrivo) return 1; else return 0;}
VoloGiornaliero getVoloGiornaliero(int giorno){return voliGiornalieri[giorno];}
public String toString(){return codiceVolo + " da " + luogoPartenza + ":" + oraPartenza + "
a " + luogoArrivo + ":" + oraArrivo;}}

G. Bruno Programmazione a oggetti 309


VoloGiornaliero
package voli;
import java.util.*;
public class VoloGiornaliero {
private TreeSet<String> prenotazioni;
private Volo volo;
private int giorno;
VoloGiornaliero(Volo volo, int giorno){
this.volo = volo; this.giorno = giorno;
prenotazioni = new TreeSet<String>();}
public String toString(){
return giorno + " " + volo.toString() +" " + prenotazioni;}
void addPrenotazione(String passeggero) throws VoliEx{
if (prenotazioni.size() == volo.getAereo().getNumeroPosti())
throw new VoliEx("volo completo:" + volo.getCodiceVolo() + ":" + giorno);
if (!prenotazioni.add(passeggero)) throw
new VoliEx("prenotazione duplicata:" + volo.getCodiceVolo() + ":" + giorno + " " + passeggero);
}}

G. Bruno Programmazione a oggetti 310


Dieta

G. Bruno Programmazione a oggetti 311


Requisiti
R1 - Materie Prime
Si interagisce con il sistema tramite la classe Alimenti.
Per definire una materia prima, si utilizza il metodo definisciMateriaPrima()
che riceve come parametri il nome, le KCal, le proteine, i carboidrati e i
grassi,tutti riferiti a 100 grammi di materia prima. Per avere informazioni sulle
materie prime, si utilizza il metodo materiePrime() che restituisce la collezione
delle materie prime in ordine alfabetico. Per ottenere le informazioni su una
specifica materia prima ci si avvale del metodo getMateriaPrima() che riceve
come parametro il nome e restituisce la materia prima corrispondente.
Gli elementi restituiti dai due metodi precedenti implementano l'interfaccia
ElementoNutritivo che definisce i metodi getNome(), getCalorie(),
getProteine(), getCarboidrati(), getGrassi(). Le calorie sono espresse in KCal,
mentre proteine, carboidrati e grassi sono espressi in grammi. Inoltre
l'interfaccia definisce il metodo booleano per100G() che indica se i valori
nutritivi sono espressi per 100 grammi di elemento oppure esprimono un valore
assoluto.
Nel caso delle materie prime i valori nutritivi sono espressi sempre per 100
grammi.

G. Bruno Programmazione a oggetti 312


Requisiti
R2 - Prodotti
Il sistema tratta anche prodotti preconfezionati (ad esempio un cono gelato).
I prodotti vengono definiti tramite il metodo definisciProdotto() della classe
Alimenti che riceve come parametri il nome, le KCal totali, le proteine, i
carboidrati e i grassi, che esprimono i valori complessivi per il prodotto (il metodo
per100G() restituisce false).
Per avere informazioni sui prodotti si utilizza il metodo prodotti() della classe
Alimenti che restituisce la collezione dei prodotti in ordine alfabetico.
Per ottenere le informazioni su uno specifico prodotto ci si avvale del metodo
getProdotto() della classe Alimenti che riceve come parametro il nome e
restituisce il prodotto corrispondente.
Gli elementi restituiti dai due metodi precedenti implementano l'interfaccia
ElementoNutritivo; i valori sono espressi per prodotto (non per 100 grammi).

G. Bruno Programmazione a oggetti 313


Requisiti
R3 - Statistiche
Il metodo materiePrimePerCalorie() restituisce una collezione contenente le
materie prime ordinate per calorie crescenti.
Inoltre presente il metodo mediaCalorieProdotti() che restituisce la media
aritmetica delle KCal dei prodotti.

G. Bruno Programmazione a oggetti 314


Requisiti
R4 - Men
Un men composto da porzioni di materie prime e da prodotti preconfezionati.
Pre creare un men si utilizza il metodo definisciMenu() che riceve come
parametro il nome del men. Per aggiungere una porzione di materia prima si
usa il metodo aggiungiPorzione() che riceve come parametri il nome del menu,
il nome di una materia prima e la dimensione della porzione in grammi; se il
nome non corrisponde ad alcuna materia prima viene generata un'eccezione di
MateriaPrimaInesistente.
Per aggiungere un prodotto preconfezionato si usa il metodo
aggiungiProdotto() che riceve come parametri il nome del menu e il nome di un
prodotto; se il nome non corrisponde ad alcun prodotto viene generata
un'eccezione di ProdottoInesistente.
Infine, il metodo getMenu() riceve come parametro il nome di un men e
restituisce un oggetto che implementa l'interfaccia ElementoNutritivo; in questo
caso i valori restituiti si riferiscono al totale del menu e non ai 100 grammi.

G. Bruno Programmazione a oggetti 315


Requisiti
R5 - Lettura da file
Deve essere possibile leggere le informazioni sulle materie prime da file tramite
il metodo leggiMateriePrime() della classe Alimenti. Tale metodo riceve come
parametri il path del file contenente le informazioni. Il file un file testuale che
contiene una materia prima per ogni riga, le materie prime sono descritte con
nome, calorie, proteine, carboidrati e grassi separati da un ';'.
In caso di dati errati su una riga, il metodo deve scartare la linea e procedere con
quelle successive.

G. Bruno Programmazione a oggetti 316


Dieta
public interface ElementoNutritivo {
public String getNome();
public double getCalorie();
public double getProteine();
public double getCarboidrati();
public double getGrassi();
public boolean per100G();
}

G. Bruno Programmazione a oggetti 317


TestDieta
public static void main(String[] args) throws Exception {
Alimenti alimenti = new Alimenti();
alimenti.definisciMateriaPrima("Zucchero", 400, 0, 100, 0);
Mais cal: 70.0
alimenti.definisciMateriaPrima("Mais", 70, 2.7, 12, 1.3);
Nutella cal: 530.0
alimenti.definisciMateriaPrima("Pasta", 350, 12, 72.2, 1.5);
Olio cal: 900.0
alimenti.definisciMateriaPrima("Olio", 900, 0, 0, 100);
Pasta cal: 350.0
alimenti.definisciMateriaPrima("Nutella", 530, 6.8, 56, 31);
Zucchero cal: 400.0
for(ElementoNutritivo e : alimenti.materiePrime()){
Mais cal: 70.0
System.out.println(e.getNome() + " cal: " + e.getCalorie());
Pasta cal: 350.0
}
Zucchero cal: 400.0
for(ElementoNutritivo e : alimenti.materiePrimePerCalorie()){
Nutella cal: 530.0
System.out.println(e.getNome() + " cal: " + e.getCalorie());
Olio cal: 900.0
}

G. Bruno Programmazione a oggetti 318


Dieta
alimenti.definisciProdotto("Cracker", 111, 2.6, 17.2, 3.5);
alimenti.definisciProdotto("Cono gelato", 400, 2.6, 17.2, 3.5);
alimenti.definisciProdotto("Cracker", 111, 2.6, 17.2, 3.5);
System.out.println(" media cal. prodotti " + alimenti.mediaCalorieProdotti());
alimenti.definisciMenu("Menu 1");
alimenti.aggiungiProdotto("Menu 1", "Cracker"); media cal. prodotti 255.5
alimenti.aggiungiMateriaPrima("Menu 1", "Pasta",80); Per il menu Menu 1
alimenti.aggiungiMateriaPrima("Menu 1", "Nutella",250); Calorie : 837,00
ElementoNutritivo menu = alimenti.getMenu("Menu 1"); Carboidrati : 134,60
System.out.println("Per il menu " + menu.getNome() + Grassi : 24,00
"\n\tCalorie : " + menu.getCalorie() + Proteine : 20,60
"\n\tCarboidrati : " + menu.getCarboidrati() +
"\n\tGrassi : " + menu.getGrassi() +
"\n\tProteine : " + menu.getProteine() +"."
);}
System.out.println(menu); // notare il risultato

Menu 1[Cracker: 2.0, Pasta: 100.0, Nutella: 50.0]

G. Bruno Programmazione a oggetti 319


package dieta;
Alimenti
import java.io.*; import java.util.*;
public class Alimenti {
TreeMap<String, Alimento> materiePrime = new TreeMap<String, Alimento>();
TreeMap<String, Alimento> prodotti = new TreeMap<String, Alimento>();
TreeMap<String, Menu> menus = new TreeMap<String, Menu>();
public void definisciMateriaPrima(String nome, double kcal,
double proteine, double carboidrati, double grassi){
materiePrime.put(nome, new Alimento(nome, kcal, proteine, carboidrati, grassi));}
public Collection<? extends ElementoNutritivo> materiePrime(){
return materiePrime.values();}
public ElementoNutritivo getMateriaPrima(String nome)throws Exception{
ElementoNutritivo a = materiePrime.get(nome);
if (a == null) throw new Exception(Eccezioni.MATERIAPRIMAINESISTENTE.toString());
return a;}

G. Bruno Programmazione a oggetti 320


Alimenti
public void definisciProdotto(String nome, double kcal,
double proteine, double carboidrati, double grassi){
prodotti.put(nome, new Alimento(nome, kcal, proteine, carboidrati, grassi));}
public Collection<? extends ElementoNutritivo> prodotti(){
return prodotti.values();}
public ElementoNutritivo getProdotto(String nome)throws Exception{
ElementoNutritivo a = prodotti.get(nome);
if (a == null) throw new Exception(Eccezioni.PRODOTTOINESISTENTE.toString());
return a;}
public Collection<? extends ElementoNutritivo> materiePrimePerCalorie(){
List<Alimento> list1 = new ArrayList<Alimento>(materiePrime.values());
Collections.sort(list1); return list1;}
public double mediaCalorieProdotti(){
double media = 0;
for(ElementoNutritivo e : prodotti.values()){media += e.getCalorie();}
return media / prodotti.values().size();}

G. Bruno Programmazione a oggetti 321


Alimenti
public void definisciMenu(String nome){menus.put(nome, new Menu(nome));}
public void aggiungiMateriaPrima(String menu, String materiaPrima, double quantita)
throws Exception{Menu m = menus.get(menu);
if (m == null) throw new Exception(Eccezioni.MENUINESISTENTE.toString());
Alimento a = materiePrime.get(materiaPrima);
if (a == null) throw new Exception(Eccezioni.MATERIAPRIMAINESISTENTE.toString());
m.aggiungiMateriaPrima(a, quantita);}
public void aggiungiProdotto(String menu, String prodotto, double quantita)
throws Exception {Menu m = menus.get(menu);
if (m == null) throw new Exception(Eccezioni.MENUINESISTENTE.toString());
Alimento a = prodotti.get(prodotto);
if (a == null) throw new Exception(Eccezioni.PRODOTTOINESISTENTE.toString());
m.aggiungiProdotto(a, quantita);}
public ElementoNutritivo getMenu(String nome)throws Exception{
Menu m = menus.get(nome);
if (m == null) throw new Exception(Eccezioni.MENUINESISTENTE.toString());
return m;
}
G. Bruno Programmazione a oggetti 322
Alimenti
public void leggiMateriePrime(String fileName) throws IOException {
String line1 = null;
BufferedReader in = new BufferedReader(new FileReader(fileName));
line1 = in.readLine();
while (line1 != null) {
try {
Scanner sc = new Scanner(line1);
sc.useLocale(Locale.US); // legge il punto come virgola
String nome = sc.next(); double calorie = sc.nextDouble();
double proteine = sc.nextDouble(); double carboidrati = sc.nextDouble();
double grassi = sc.nextDouble();
materiePrime.put(nome, new Alimento(nome, calorie, proteine, carboidrati, grassi));
} catch (Exception e) {System.out.println(e.getMessage());
}
line1 = in.readLine();
};
in.close();
}
}
G. Bruno Programmazione a oggetti 323
package dieta;
Alimento
class Alimento implements ElementoNutritivo, Comparable<Alimento> {
protected String nome; protected double calorie;
protected double proteine; protected double carboidrati;
protected double grassi;
public int compareTo(Alimento a) {
if (calorie == a.calorie) return this.nome.compareTo(a.nome);
return (int) (calorie - a.calorie);}
Alimento(String nome, double calorie, double proteine, double carboidrati,
double grassi) {
this.nome = nome; this.calorie = calorie; this.proteine = proteine;
this.carboidrati = carboidrati; this.grassi = grassi; }
public double getCalorie() {return calorie;}
public double getCarboidrati() {return carboidrati;}
public double getGrassi() {return grassi;}
public String getNome() {return nome;}
public double getProteine() {return proteine;}
protected Alimento (String nome) {this.nome = nome;}}

G. Bruno Programmazione a oggetti 324


package dieta;
import java.util.*; Menu
class Menu extends Alimento{
private List<Quantita> componenti = new ArrayList<Quantita>();
public Menu(String nome) {super(nome);}
private class Quantita {Alimento a; double quantita;
Quantita (Alimento e, double quantita) {this.a = e; this.quantita = quantita;}
public String toString() {return a.getNome() + ": " + quantita;}}
void aggiungiMateriaPrima(Alimento a, double quantita) {
componenti.add(new Quantita(a, quantita));
aggiungi(a, quantita);}
void aggiungiProdotto(Alimento a, double quantita) {
componenti.add(new Quantita(a, quantita));
aggiungi(a, quantita * 100);}
private void aggiungi(Alimento a, double quantita){
calorie += a.getCalorie() / 100.0 * quantita; proteine += a.getProteine() / 100.0 * quantita;
carboidrati += a.getCarboidrati() / 100.0 * quantita; grassi += a.getGrassi() / 100.0 * quantita;}
public String toString() {return nome + componenti;}
}

G. Bruno Programmazione a oggetti 325


Eccezioni
package dieta;
enum Eccezioni {
MATERIAPRIMAINESISTENTE, PRODOTTOINESISTENTE,
MENUINESISTENTE
}

G. Bruno Programmazione a oggetti 326


Pubblicazioni
Sviluppare l'applicazione che consente di valutare l'attivit di ricercatori tramite le loro
pubblicazioni. Tutte le classi devono essere nel package "ricerca".

R1 - Ricercatori
L'interazione con il sistema avviene tramite la classe Valutazione.
possibile inserire i dati di un nuovo ricercatore tramite il metodo addRicercatore() che
riceve come parametri un codice univoco, nome e cognome; il metodo restituisce un oggetto
di tipo Ricercatore.
La classe Ricercatore permette di conoscere codice, nome e cognome tramite i metodi
getCodice(), getFirst() e getLast(). Per ottenere uno specifico ricercatore si usa il
metodo getRicercatore().

R2 - Riviste
Per inserire delle riviste nel sistema si utilizza il metodo addRivista() che riceve come
parametri il codice ISSN, il nome (titolo) della rivista e l'Impact Factor, che un indice che
rappresenta la bont della rivista. Il metodo restituisce un oggetto di classe Rivista, la
quale offre i metodi getTitolo() e getIF() per accedere al titolo e all'Impact Factor della
rivista.
Per poter ottenere una rivista specifica si utilizza il metodo getRivista() che riceve come
parametro il codice ISSN. Il metodo getRiviste() restituisce la lista delle riviste in ordine
di Impact Factor decrescente.

G. Bruno Programmazione a oggetti 327


Pubblicazioni
R3 - Articoli
Gli articoli pubblicati sulle riviste vengono inseriti tramite il metodo
addArticolo() della classe Rivista che riceve come parametri il titolo
dell'articolo e l'autore; il metodo restituisce un oggetto di classe Articolo. Il titolo
accessibile tramite il metodo getTitolo().
Per inserire articoli con pi autori si utilizza la versione dello stesso metodo che
riceve come ultimo parametro un array di autori. Per ottenere l'elenco degli
autori si utilizza il metodo elencoAutori().
possibile sapere il numero degli articoli pubblicati da un dato ricercatore
tramite il metodo numArticoli() della classe Ricercatore.

G. Bruno Programmazione a oggetti 328


R4 - Indici e citazioni
Pubblicazioni
Si devono poter calcolare due diversi indici di produttivit dei ricercatori.
Il metodo sommaIF() della classe Ricercatore calcola la somma degli Impact Factor delle
riviste per ogni articolo pubblicato dal ricercatore.
Il metodo cita() della classe Articolo riceve come parametro un articolo e permette di
definire una citazione ad esso. Ad esempio, "a1.cita(a2)" inserisce una nuova citazione
dell'articolo a2 da parte dell'articolo a1. Il numero di citazioni di un articolo ottenibile
tramite il metodo numCitazioni().
Il metodo hIndex() della classe Ricercatore calcola l'h-index dell'autore nel modo seguente:
si ordinano gli articoli dell'autore in ordine decrescente per numero di citazioni,
h-index = max( i | citazioni(articoli[i]) >= i ).
Se un ricercatore non ha articoli, oppure se i suoi articoli hanno n. di citazioni = 0, allora il
suo hIndex vale 0. Quindi se un autore ha h-Index n vuol dire che n articoli di cui autore
hanno ricevuto almeno n citazioni. Ad esempio, dati i seguenti articoli, l'h-index = 4:
Pos. Articolo Num citazioni
1 Art y 50
2 Art z 40
3 Art s 10
4 Art x 5
5 Art t 4
G. Bruno Programmazione a oggetti 329
Pubblicazioni
R5 - Lettura da file
possibile leggere i dati relativi alla ricerca da un file di testo organizzato come
segue tramite il metodo leggi(). Gli elementi sono memorizzati per righe e il loro
tipo definito dalla prima lettera della linea. I dati degli elementi sono separati
da ';'.
I ricercatori sono identificati dalla 'R', seguita dal codice, nome e cognome.
Le riviste sono identificate dalla 'J', seguita da ISSN, nome e Impact Factor.
Gli articoli sono identificati dalla 'A', seguita da ISSN, titolo, codice dell'autore
(non si considerano i casi di autori multipli) e numero di citazioni.
In caso di errore su una linea il metodo deve ignorare la linea e proseguire la
lettura del file.
Esempio:
R;123;Albert;Einstein
J;0031-9007;Physical Review Letters;7.072
A;0031-9007;Teoria della relativita ristretta;123;1246
Si intende che prima siano elencati i ricercatori, poi le riviste e gli articoli.

G. Bruno Programmazione a oggetti 330


TestRicerca
import ricerca.*;
public class TestRicerca {
public static void main(String[] args) {
Valutazione v = new Valutazione();
Ricercatore ae = v.addRicercatore("123","Albert","Einstein");
Ricercatore ef = v.addRicercatore("432","Enrico","Fermi");
Ricercatore nb = v.addRicercatore("123","Niels","Bohr");
Ricercatore[] autori1 = {ef, nb};
Rivista pr = v.addRivista("0031-9007","Physical Review Letters",7.072);
Rivista ap = v.addRivista("0001-8732","Advances in Physics",9.571);
for (Rivista r: v.getRiviste()) System.out.println(r.getTitolo() + " " + r.getIF());
Articolo a1 = pr.addArticolo("Teoria della relativita ristretta",ae);
Articolo a2 = ap.addArticolo("Teoria della relativita generale",ae);
Articolo a3 = ap.addArticolo("Teoria e pratica della fissione",ef);
Articolo a4 = pr.addArticolo("Un modello dell'atomo",nb);
Articolo a5 = pr.addArticolo("Titolo5", autori1);
System.out.println(ef.getLast() + " ha pubblicato " + ef.numArticoli());
System.out.println(ae.getLast() + " ha pubblicato " + ae.numArticoli());
System.out.println(ae.getLast() + " ha totalizzato " + ae.sommaIF());

G. Bruno Programmazione a oggetti 331


Advances in Physics 9.571
Physical Review Letters 7.072
Valutazione Fermi ha pubblicato 2
Einstein ha pubblicato 2
Einstein ha totalizzato 16.643
Einstein ha h-index 2
Teoria della relativita ristretta 3
Teoria della relativita generale 2
Physical Review Letters 7.072
a4.cita(a1); a3.cita(a1); a1.cita(a2); Einstein ha pubblicato 1
Einstein ha h-index 1
a4.cita(a2); a3.cita(a2); a3.cita(a4);

System.out.println(ae.getLast() + " ha h-index " + ae.hIndex());

for (Articolo a: ae.elencoArticoli())


System.out.println(a.getTitolo() + " " + a.numCitazioni());

v = new Valutazione();

v.leggi("dati");
for (Rivista r: v.getRiviste()) System.out.println(r.getTitolo() + " " + r.getIF());
ae = v.getRicercatore("123");
System.out.println(ae.getLast() + " ha pubblicato " + ae.numArticoli());
System.out.println(ae.getLast() + " ha h-index " + ae.hIndex());}}

G. Bruno Programmazione a oggetti 332


Valutazione
Valutazione
HM(codice) HM(issn)
Ricercatore Rivista C
AL 1
Articolo C
AL AL
Attributi
Ricercatore: String codice, first, last.
Rivista: String issn, title; double impactFactor.
Articolo: String titolo; int n.
Valutazione: HM(codice) ricercatori; HM(issn) riviste.

AL = ArrayList
HM = HashMap

G. Bruno Programmazione a oggetti 333


package ricerca;
Valutazione
import java.io.*; import java.util.*;
public class Valutazione {
Map<String, Ricercatore> ricercatori = new HashMap<String, Ricercatore>();
Map<String, Rivista> riviste = new HashMap<String, Rivista>();
public Ricercatore addRicercatore (String id, String first, String last) {
Ricercatore r = new Ricercatore(id, first, last); ricercatori.put(id, r); return r;}
public Ricercatore getRicercatore (String id){return ricercatori.get(id);}
public Rivista addRivista (String issn, String title, double impactFactor) {
Rivista r = new Rivista(issn, title, impactFactor); riviste.put(issn, r); return r;}
public Rivista getRivista (String issn){return riviste.get(issn);}
public Collection<Rivista> getRiviste() {
List<Rivista> list1 = new ArrayList<Rivista>(riviste.values());
Collections.sort(list1); return list1;}

G. Bruno Programmazione a oggetti 334


public void leggi(String fileName) { Valutazione
try { String line1 = null;
BufferedReader in = new BufferedReader(new FileReader(fileName));
line1 = in.readLine();
while (line1 != null) {
try {
Scanner sc = new Scanner(line1).useDelimiter(";"); String l = sc.next();
if (l.equals("R")) {String id = sc.next(); String first = sc.next(); String last = sc.next();
addRicercatore(id, first, last);
} else if (l.equals("J")) {String issn = sc.next(); String title = sc.next();
double impactFactor = sc.nextDouble(); addRivista(issn, title, impactFactor);
} else if (l.equals("A")) {String issn = sc.next(); String title = sc.next();
String id = sc.next(); int n = sc.nextInt(); Rivista r = getRivista(issn);
Ricercatore ricercatore = getRicercatore(id); r.addArticolo(title, ricercatore, n);
} } catch (Exception e) {//e.printStackTrace(); }
line1 = in.readLine();
};
in.close(); } catch (Exception e) { //e.printStackTrace(); }
}}

G. Bruno Programmazione a oggetti 335


package ricerca; Ricercatore
import java.util.*;
public class Ricercatore {
private String codice; private String first; private String last;
private ArrayList<Articolo> articoli = new ArrayList<Articolo>();
Ricercatore (String codice, String first, String last) {
this.codice = codice; this.first = first; this.last = last;}
public String getCodice (){return codice;} public String getFirst (){return first;}
public String getLast (){return last;} public int numArticoli () {return articoli.size();}
void addArticolo (Articolo a) {articoli.add(a);}
public double sommaIF () {
double f = 0; for (Articolo a: articoli) f += a.getRivista().getIF(); return f;}
public int hIndex () {
Collections.sort(articoli); // da aggiungere al codice del workspace
int i = 1; int val = 0;
for (Articolo a: articoli) if (a.numCitazioni() < i) return val; else val = i++;
return val;}
public Collection<Articolo> elencoArticoli (){return articoli;}
}

G. Bruno Programmazione a oggetti 336


package ricerca;
import java.util.*; @SuppressWarnings("unused")
Rivista
public class Rivista implements Comparable <Rivista> {
private String issn; private String title; private double impactFactor;
private ArrayList<Articolo> articoli = new ArrayList<Articolo>();
Rivista (String issn, String title, double impactFactor) {
this.issn = issn; this.title = title; this.impactFactor = impactFactor;}
public String getTitolo(){return title;} public double getIF(){return impactFactor;}
public Articolo addArticolo (String titolo, Ricercatore ricercatore) {
Articolo a = new Articolo(titolo, ricercatore, this); articoli.add(a);
ricercatore.addArticolo(a); return a;}
public Articolo addArticolo (String titolo, Ricercatore ricercatore, int n) {
Articolo a = new Articolo(titolo, ricercatore, this, n); articoli.add(a);
ricercatore.addArticolo(a); return a;}
public Articolo addArticolo (String titolo, Ricercatore[] ricercatori) {
Articolo a = new Articolo(titolo, ricercatori, this); articoli.add(a);
for (Ricercatore r: ricercatori) r.addArticolo(a); return a;}
public int compareTo (Rivista r) {if (this.impactFactor == r.impactFactor) return 0;
else if (this.impactFactor < r.impactFactor) return 1; else return -1;
}}

G. Bruno Programmazione a oggetti 337


package ricerca; Articolo
import java.util.*;
public class Articolo implements Comparable <Articolo> {
private String titolo; private int n = 0; private Rivista r;
private Collection<Ricercatore> autori = new ArrayList<Ricercatore>();
Articolo (String titolo, Ricercatore ricercatore, Rivista r) {
this.titolo = titolo; this.autori.add(ricercatore); this.r = r;}
Articolo (String titolo, Ricercatore[] ricercatori, Rivista r) {
this.titolo = titolo; this.autori = Arrays.asList(ricercatori); this.r = r;}
Articolo (String titolo, Ricercatore ricercatore, Rivista r, int n) {
this.titolo = titolo; this.autori.add(ricercatore); this.r = r; this.n = n;}
public Rivista getRivista(){return r;}
public String getTitolo(){return titolo;}
public Collection<Ricercatore> elencoAutori(){return autori;}
public void cita(Articolo citato) {citato.n++;}
public int numCitazioni(){return n;}
public int compareTo(Articolo a) {if (this.n == a.n) return 0;
else if (this.n < a.n) return 1; else return -1;} }

G. Bruno Programmazione a oggetti 338