diff --git a/.gitignore b/.gitignore
index 767e5c7..342b181 100644
--- a/.gitignore
+++ b/.gitignore
@@ -22,6 +22,8 @@
hs_err_pid*
# IntelliJ
-.idea/*
-**/.idea/*
+#.idea/*
+#**/.idea/*
+**/.vs/*
+**/x64/*
diff --git a/2018/pitagora/pitagora.iml b/2017-18/pitagora/pitagora.iml
similarity index 100%
rename from 2018/pitagora/pitagora.iml
rename to 2017-18/pitagora/pitagora.iml
diff --git a/2018/pitagora/src/it/unive/dais/po/pitagora/Lato.java b/2017-18/pitagora/src/it/unive/dais/po/pitagora/Lato.java
similarity index 100%
rename from 2018/pitagora/src/it/unive/dais/po/pitagora/Lato.java
rename to 2017-18/pitagora/src/it/unive/dais/po/pitagora/Lato.java
diff --git a/2018/pitagora/src/it/unive/dais/po/pitagora/Main.java b/2017-18/pitagora/src/it/unive/dais/po/pitagora/Main.java
similarity index 100%
rename from 2018/pitagora/src/it/unive/dais/po/pitagora/Main.java
rename to 2017-18/pitagora/src/it/unive/dais/po/pitagora/Main.java
diff --git a/2018/pitagora/src/it/unive/dais/po/pitagora/Numeric.java b/2017-18/pitagora/src/it/unive/dais/po/pitagora/Numeric.java
similarity index 100%
rename from 2018/pitagora/src/it/unive/dais/po/pitagora/Numeric.java
rename to 2017-18/pitagora/src/it/unive/dais/po/pitagora/Numeric.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/Main.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/Main.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/Main.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/Main.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/MyIterable.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/MyIterable.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/MyIterable.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/MyIterable.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/MyIterator.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/MyIterator.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/MyIterator.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/MyIterator.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/MyList.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/MyList.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/MyList.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/MyList.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/MyNode.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/MyNode.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/MyNode.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/MyNode.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/MyNodeList.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/MyNodeList.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/MyNodeList.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/MyNodeList.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/MyNodeListIterator.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/MyNodeListIterator.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/MyNodeListIterator.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/MyNodeListIterator.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/MySequence.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/MySequence.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/MySequence.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/MySequence.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/NotFoundException.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/NotFoundException.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/NotFoundException.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/NotFoundException.java
diff --git a/2018/tinylib/src/it/unive/dais/po/tinylib/OverloadTest.java b/2017-18/tinylib/src/it/unive/dais/po/tinylib/OverloadTest.java
similarity index 100%
rename from 2018/tinylib/src/it/unive/dais/po/tinylib/OverloadTest.java
rename to 2017-18/tinylib/src/it/unive/dais/po/tinylib/OverloadTest.java
diff --git a/2018/tinylib/tinylib.iml b/2017-18/tinylib/tinylib.iml
similarity index 100%
rename from 2018/tinylib/tinylib.iml
rename to 2017-18/tinylib/tinylib.iml
diff --git a/2019/TinyJDK/TinyJDK.iml b/2018-19/TinyJDK/TinyJDK.iml
similarity index 100%
rename from 2019/TinyJDK/TinyJDK.iml
rename to 2018-19/TinyJDK/TinyJDK.iml
diff --git a/2019/TinyJDK/out/production/TinyJDK/META-INF/TinyJDK.kotlin_module b/2018-19/TinyJDK/out/production/TinyJDK/META-INF/TinyJDK.kotlin_module
similarity index 100%
rename from 2019/TinyJDK/out/production/TinyJDK/META-INF/TinyJDK.kotlin_module
rename to 2018-19/TinyJDK/out/production/TinyJDK/META-INF/TinyJDK.kotlin_module
diff --git a/2019/TinyJDK/out/production/TinyJDK/TinyJDK.iml b/2018-19/TinyJDK/out/production/TinyJDK/TinyJDK.iml
similarity index 100%
rename from 2019/TinyJDK/out/production/TinyJDK/TinyJDK.iml
rename to 2018-19/TinyJDK/out/production/TinyJDK/TinyJDK.iml
diff --git a/2019/TinyJDK/src/collections/Main.java b/2018-19/TinyJDK/src/collections/Main.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/Main.java
rename to 2018-19/TinyJDK/src/collections/Main.java
diff --git a/2019/TinyJDK/src/collections/MyAbstractArrayListSet.java b/2018-19/TinyJDK/src/collections/MyAbstractArrayListSet.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyAbstractArrayListSet.java
rename to 2018-19/TinyJDK/src/collections/MyAbstractArrayListSet.java
diff --git a/2019/TinyJDK/src/collections/MyArrayList.java b/2018-19/TinyJDK/src/collections/MyArrayList.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyArrayList.java
rename to 2018-19/TinyJDK/src/collections/MyArrayList.java
diff --git a/2019/TinyJDK/src/collections/MyArrayListSet.java b/2018-19/TinyJDK/src/collections/MyArrayListSet.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyArrayListSet.java
rename to 2018-19/TinyJDK/src/collections/MyArrayListSet.java
diff --git a/2019/TinyJDK/src/collections/MyArrayListSortedSet.java b/2018-19/TinyJDK/src/collections/MyArrayListSortedSet.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyArrayListSortedSet.java
rename to 2018-19/TinyJDK/src/collections/MyArrayListSortedSet.java
diff --git a/2019/TinyJDK/src/collections/MyCollection.java b/2018-19/TinyJDK/src/collections/MyCollection.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyCollection.java
rename to 2018-19/TinyJDK/src/collections/MyCollection.java
diff --git a/2019/TinyJDK/src/collections/MyIterable.java b/2018-19/TinyJDK/src/collections/MyIterable.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyIterable.java
rename to 2018-19/TinyJDK/src/collections/MyIterable.java
diff --git a/2019/TinyJDK/src/collections/MyIterator.java b/2018-19/TinyJDK/src/collections/MyIterator.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyIterator.java
rename to 2018-19/TinyJDK/src/collections/MyIterator.java
diff --git a/2019/TinyJDK/src/collections/MyList.java b/2018-19/TinyJDK/src/collections/MyList.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyList.java
rename to 2018-19/TinyJDK/src/collections/MyList.java
diff --git a/2019/TinyJDK/src/collections/MyListMap.java b/2018-19/TinyJDK/src/collections/MyListMap.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyListMap.java
rename to 2018-19/TinyJDK/src/collections/MyListMap.java
diff --git a/2019/TinyJDK/src/collections/MyMap.java b/2018-19/TinyJDK/src/collections/MyMap.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MyMap.java
rename to 2018-19/TinyJDK/src/collections/MyMap.java
diff --git a/2019/TinyJDK/src/collections/MySet.java b/2018-19/TinyJDK/src/collections/MySet.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MySet.java
rename to 2018-19/TinyJDK/src/collections/MySet.java
diff --git a/2019/TinyJDK/src/collections/MySortedSet.java b/2018-19/TinyJDK/src/collections/MySortedSet.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/MySortedSet.java
rename to 2018-19/TinyJDK/src/collections/MySortedSet.java
diff --git a/2019/TinyJDK/src/collections/NotFoundException.java b/2018-19/TinyJDK/src/collections/NotFoundException.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/NotFoundException.java
rename to 2018-19/TinyJDK/src/collections/NotFoundException.java
diff --git a/2019/TinyJDK/src/collections/Pair.java b/2018-19/TinyJDK/src/collections/Pair.java
similarity index 100%
rename from 2019/TinyJDK/src/collections/Pair.java
rename to 2018-19/TinyJDK/src/collections/Pair.java
diff --git a/2019/TinyJDK/src/misc/AbstractErrors.java b/2018-19/TinyJDK/src/misc/AbstractErrors.java
similarity index 100%
rename from 2019/TinyJDK/src/misc/AbstractErrors.java
rename to 2018-19/TinyJDK/src/misc/AbstractErrors.java
diff --git a/2019/TinyJDK/src/misc/ErrorInInvoke.java b/2018-19/TinyJDK/src/misc/ErrorInInvoke.java
similarity index 100%
rename from 2019/TinyJDK/src/misc/ErrorInInvoke.java
rename to 2018-19/TinyJDK/src/misc/ErrorInInvoke.java
diff --git a/2019/TinyJDK/src/misc/GenericSort.java b/2018-19/TinyJDK/src/misc/GenericSort.java
similarity index 100%
rename from 2019/TinyJDK/src/misc/GenericSort.java
rename to 2018-19/TinyJDK/src/misc/GenericSort.java
diff --git a/2019/TinyJDK/src/patterns/consumer_producer/Main.java b/2018-19/TinyJDK/src/patterns/consumer_producer/Main.java
similarity index 100%
rename from 2019/TinyJDK/src/patterns/consumer_producer/Main.java
rename to 2018-19/TinyJDK/src/patterns/consumer_producer/Main.java
diff --git a/2019/TinyJDK/src/patterns/singleton/Main.java b/2018-19/TinyJDK/src/patterns/singleton/Main.java
similarity index 100%
rename from 2019/TinyJDK/src/patterns/singleton/Main.java
rename to 2018-19/TinyJDK/src/patterns/singleton/Main.java
diff --git a/2019/TinyJDK/src/patterns/singleton/RandomSingleton.java b/2018-19/TinyJDK/src/patterns/singleton/RandomSingleton.java
similarity index 100%
rename from 2019/TinyJDK/src/patterns/singleton/RandomSingleton.java
rename to 2018-19/TinyJDK/src/patterns/singleton/RandomSingleton.java
diff --git a/2019/TinyJDK/src/threads/SynchronizedMain.java b/2018-19/TinyJDK/src/threads/SynchronizedMain.java
similarity index 100%
rename from 2019/TinyJDK/src/threads/SynchronizedMain.java
rename to 2018-19/TinyJDK/src/threads/SynchronizedMain.java
diff --git a/2019/TinyJDK/src/threads/pool/Main.java b/2018-19/TinyJDK/src/threads/pool/Main.java
similarity index 100%
rename from 2019/TinyJDK/src/threads/pool/Main.java
rename to 2018-19/TinyJDK/src/threads/pool/Main.java
diff --git a/2019/TinyJDK/src/threads/pool/ThreadPool.java b/2018-19/TinyJDK/src/threads/pool/ThreadPool.java
similarity index 100%
rename from 2019/TinyJDK/src/threads/pool/ThreadPool.java
rename to 2018-19/TinyJDK/src/threads/pool/ThreadPool.java
diff --git a/2019/lezione18-19/lezione18-19.iml b/2018-19/lezione18-19/lezione18-19.iml
similarity index 100%
rename from 2019/lezione18-19/lezione18-19.iml
rename to 2018-19/lezione18-19/lezione18-19.iml
diff --git a/2019/lezione18-19/out/production/lezione18-19/META-INF/lezione18-19.kotlin_module b/2018-19/lezione18-19/out/production/lezione18-19/META-INF/lezione18-19.kotlin_module
similarity index 100%
rename from 2019/lezione18-19/out/production/lezione18-19/META-INF/lezione18-19.kotlin_module
rename to 2018-19/lezione18-19/out/production/lezione18-19/META-INF/lezione18-19.kotlin_module
diff --git a/2019/lezione18-19/src/Main__Collections.java b/2018-19/lezione18-19/src/Main__Collections.java
similarity index 100%
rename from 2019/lezione18-19/src/Main__Collections.java
rename to 2018-19/lezione18-19/src/Main__Collections.java
diff --git a/2019/lezione18-19/src/Main__Experiments.java b/2018-19/lezione18-19/src/Main__Experiments.java
similarity index 100%
rename from 2019/lezione18-19/src/Main__Experiments.java
rename to 2018-19/lezione18-19/src/Main__Experiments.java
diff --git a/2019/lezione18-19/src/Main__Functional.java b/2018-19/lezione18-19/src/Main__Functional.java
similarity index 100%
rename from 2019/lezione18-19/src/Main__Functional.java
rename to 2018-19/lezione18-19/src/Main__Functional.java
diff --git a/2019/lezione18-19/src/collections/MyArrayList.java b/2018-19/lezione18-19/src/collections/MyArrayList.java
similarity index 100%
rename from 2019/lezione18-19/src/collections/MyArrayList.java
rename to 2018-19/lezione18-19/src/collections/MyArrayList.java
diff --git a/2019/lezione18-19/src/collections/MyCollection.java b/2018-19/lezione18-19/src/collections/MyCollection.java
similarity index 100%
rename from 2019/lezione18-19/src/collections/MyCollection.java
rename to 2018-19/lezione18-19/src/collections/MyCollection.java
diff --git a/2019/lezione18-19/src/collections/MyIterator.java b/2018-19/lezione18-19/src/collections/MyIterator.java
similarity index 100%
rename from 2019/lezione18-19/src/collections/MyIterator.java
rename to 2018-19/lezione18-19/src/collections/MyIterator.java
diff --git a/2019/lezione18-19/src/collections/Pair.java b/2018-19/lezione18-19/src/collections/Pair.java
similarity index 100%
rename from 2019/lezione18-19/src/collections/Pair.java
rename to 2018-19/lezione18-19/src/collections/Pair.java
diff --git a/2019/lezione18-19/src/zoo/Animale.java b/2018-19/lezione18-19/src/zoo/Animale.java
similarity index 100%
rename from 2019/lezione18-19/src/zoo/Animale.java
rename to 2018-19/lezione18-19/src/zoo/Animale.java
diff --git a/2019/lezione18-19/src/zoo/Cane.java b/2018-19/lezione18-19/src/zoo/Cane.java
similarity index 100%
rename from 2019/lezione18-19/src/zoo/Cane.java
rename to 2018-19/lezione18-19/src/zoo/Cane.java
diff --git a/2019/lezione18-19/src/zoo/Gatto.java b/2018-19/lezione18-19/src/zoo/Gatto.java
similarity index 100%
rename from 2019/lezione18-19/src/zoo/Gatto.java
rename to 2018-19/lezione18-19/src/zoo/Gatto.java
diff --git a/2019/lezione18-19/src/zoo/PastoreTedesco.java b/2018-19/lezione18-19/src/zoo/PastoreTedesco.java
similarity index 100%
rename from 2019/lezione18-19/src/zoo/PastoreTedesco.java
rename to 2018-19/lezione18-19/src/zoo/PastoreTedesco.java
diff --git a/2019-20/Lezioni/.idea/codeStyles/codeStyleConfig.xml b/2019-20/Lezioni/.idea/codeStyles/codeStyleConfig.xml
new file mode 100644
index 0000000..a55e7a1
--- /dev/null
+++ b/2019-20/Lezioni/.idea/codeStyles/codeStyleConfig.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/2019-20/Lezioni/.idea/description.html b/2019-20/Lezioni/.idea/description.html
new file mode 100644
index 0000000..db5f129
--- /dev/null
+++ b/2019-20/Lezioni/.idea/description.html
@@ -0,0 +1 @@
+Simple Java application that includes a class with main() method
\ No newline at end of file
diff --git a/2019-20/Lezioni/.idea/inspectionProfiles/Project_Default.xml b/2019-20/Lezioni/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..6da4be7
--- /dev/null
+++ b/2019-20/Lezioni/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2019-20/Lezioni/.idea/misc.xml b/2019-20/Lezioni/.idea/misc.xml
new file mode 100644
index 0000000..1e6469c
--- /dev/null
+++ b/2019-20/Lezioni/.idea/misc.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2019-20/Lezioni/.idea/modules.xml b/2019-20/Lezioni/.idea/modules.xml
new file mode 100644
index 0000000..8617dec
--- /dev/null
+++ b/2019-20/Lezioni/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2019-20/Lezioni/.idea/project-template.xml b/2019-20/Lezioni/.idea/project-template.xml
new file mode 100644
index 0000000..1f08b88
--- /dev/null
+++ b/2019-20/Lezioni/.idea/project-template.xml
@@ -0,0 +1,3 @@
+
+ IJ_BASE_PACKAGE
+
\ No newline at end of file
diff --git a/2019-20/Lezioni/.idea/uiDesigner.xml b/2019-20/Lezioni/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/2019-20/Lezioni/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/2019-20/Lezioni/.idea/vcs.xml b/2019-20/Lezioni/.idea/vcs.xml
new file mode 100644
index 0000000..b2bdec2
--- /dev/null
+++ b/2019-20/Lezioni/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2019-20/Lezioni/.idea/workspace.xml b/2019-20/Lezioni/.idea/workspace.xml
new file mode 100644
index 0000000..6c92eb0
--- /dev/null
+++ b/2019-20/Lezioni/.idea/workspace.xml
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ C:\Users\spano\AppData\Roaming\Subversion
+
+
+
+
+ 1583492471839
+
+
+ 1583492471839
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ file://$PROJECT_DIR$/src/it/unive/dais/po2/other/ForEachTest.java
+ 12
+
+
+
+ file://$PROJECT_DIR$/src/esercizi/EsercizioCache.java
+ 36
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2019-20/Lezioni/Lezioni.iml b/2019-20/Lezioni/Lezioni.iml
new file mode 100644
index 0000000..ac9b28d
--- /dev/null
+++ b/2019-20/Lezioni/Lezioni.iml
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/2019-20/Lezioni/out/production/Lezioni/META-INF/Lezioni.kotlin_module b/2019-20/Lezioni/out/production/Lezioni/META-INF/Lezioni.kotlin_module
new file mode 100644
index 0000000..a49347a
Binary files /dev/null and b/2019-20/Lezioni/out/production/Lezioni/META-INF/Lezioni.kotlin_module differ
diff --git a/2019-20/Lezioni/src/esercizi/Andrei.java b/2019-20/Lezioni/src/esercizi/Andrei.java
new file mode 100644
index 0000000..b438d05
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/Andrei.java
@@ -0,0 +1,154 @@
+package esercizi;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+import java.util.function.Function;
+
+public class Andrei {
+
+ public static class Point {
+ public final double x, y, z;
+
+ public Point(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ public Point move(double dx, double dy, double dz) {
+ return new Point(this.x + dx, this.y + dy, this.z + dz);
+ }
+
+ @Override
+ public String toString() {
+ return String.format("(%g, %g, %g)", x, y, z);
+ }
+ }
+
+ public interface Solid extends Comparable {
+ double area();
+
+ double volume();
+
+ PositionedSolid at(Point origin);
+
+ static int compareBy(Function f, S s1, S s2) {
+ return Double.compare(f.apply(s1), f.apply(s2));
+ }
+
+ static Comparator comparatorBy(Function f) {
+ return (s1, s2) -> compareBy(f, s1, s2);
+ }
+
+ default int compareTo(Solid s) {
+ return compareBy(Solid::volume, this, s);
+ }
+
+ }
+
+ public interface Polyhedron extends Solid {
+ double perimeter();
+
+ @Override
+ PositionedPolyhedron at(Point origin);
+ }
+
+ public interface PositionedSolid {
+ Point origin();
+ }
+
+ public interface PositionedPolyhedron extends PositionedSolid, Iterable {
+ }
+
+ public static class Cube implements Polyhedron {
+ private double side;
+
+ public Cube(double side) {
+ this.side = side;
+ }
+
+ @Override
+ public double area() {
+ return 4 * Math.pow(side, 2);
+ }
+
+ @Override
+ public double volume() {
+ return Math.pow(side, 3);
+ }
+
+ @Override
+ public double perimeter() {
+ return side * 12;
+ }
+
+ @Override
+ public PositionedPolyhedron at(Point origin) {
+ return new PositionedPolyhedron() {
+ @Override
+ public Point origin() {
+ return origin;
+ }
+
+ @NotNull
+ @Override
+ public Iterator iterator() {
+ Point[] vertici = {origin, origin.move(side, 0, 0), origin.move(0, side, 0), origin.move(0, side, 0), origin.move(side, side, 0), origin.move(side, 0, side)/*ecc*/};
+ return Arrays.asList(vertici).iterator();
+ }
+ };
+ }
+
+ }
+
+ static class Sphere implements Solid {
+ private double ray;
+
+ public Sphere(double ray) {
+ this.ray = ray;
+ }
+
+ @Override
+ public double area() {
+ return 4 * 3.14 * Math.pow(ray, 2);
+ }
+
+ @Override
+ public double volume() {
+ return (4. / 3.) * 3.14 * Math.pow(ray, 3);
+ }
+
+ @Override
+ public PositionedSolid at(Point origin) {
+ return new PositionedSolid() {
+ @Override
+ public Point origin() {
+ return origin;
+ }
+ };
+ }
+ }
+
+ public static void main(String[] args) {
+
+ Cube cube1 = new Cube(11.), cube2 = new Cube(23.);
+ Sphere sphere1 = new Sphere(12.), sphere2 = new Sphere(35.);
+ List solids = List.of(cube1, cube2, sphere1, sphere2);
+ List cubes = new ArrayList<>(List.of(cube1, cube2));
+ List spheres = List.of(sphere1, sphere2);
+ List extends Polyhedron> polys = cubes;
+
+ Collections.sort(cubes);
+
+
+ Point o = new Point(1., -1.5, 2.);
+ for (Polyhedron poly : polys) {
+ for (Point p : poly.at(o)) {
+ System.out.println(p); //question mark?
+ }
+ }
+ }
+
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/DynamicDispatch.java b/2019-20/Lezioni/src/esercizi/DynamicDispatch.java
new file mode 100644
index 0000000..ebd5a1f
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/DynamicDispatch.java
@@ -0,0 +1,73 @@
+package esercizi;
+
+public class DynamicDispatch {
+
+ public static class A {
+
+ public void m() {
+ System.out.println("A::m");
+ }
+
+ public void p(int n) {}
+ public void p(double n) {}
+
+ }
+ /*
+ A
+ SLOT1: m --> A::m
+ SLOT2: p(int) --> A::p(int)
+ SLOT3: p(double) --> A::p(double)
+
+ B
+ SUPER: A
+ SLOT1: m --> B::m
+ SLOT2: p(int) --> A::p(int)
+ SLOT3: p(double) --> A::p(double)
+ SLOT4: p(String) --> B::p(String)
+ SLOT5: q(String) --> B::q(String)
+ */
+
+ public static class B extends A {
+
+ @Override
+ public void m() {
+ System.out.println("B::m");
+ }
+
+ public void p(String n) {}
+ public void q(String n) {}
+ }
+
+ public static class C {
+
+ public void a() {}
+ public void p(String n) {}
+ public void q(String n) {}
+ public void m() {
+ System.out.println("C::m");
+ }
+ }
+
+ /*
+ D
+ SUPER: B
+ SLOT1: m --> B::m
+ SLOT2: p(int) --> A::p(int)
+ SLOT3: p(double) --> A::p(double)
+ SLOT4: p(String) --> B::p(String)
+ SLOT5: q(String) --> D::q(String)
+ */
+ public static class D extends B {
+ @Override
+ public void q(String s) {}
+ }
+
+ public static void main(String[] args) {
+ A a = new B();
+ a.m();
+
+ B b = new D();
+ b.q("ciao");
+ }
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/Es_RandomIterator.java b/2019-20/Lezioni/src/esercizi/Es_RandomIterator.java
new file mode 100644
index 0000000..55aa55f
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/Es_RandomIterator.java
@@ -0,0 +1,65 @@
+package esercizi;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Iterator;
+import java.util.Random;
+
+public class Es_RandomIterator {
+
+ public static void main2(String[] args) {
+ Iterator it = new RandomIterator(10, -50, 20);
+ int cnt = 0;
+ while(it.hasNext()) {
+ int n = it.next();
+ System.out.println(String.format("#%d: %d", cnt++, n));
+ }
+ }
+
+ public static void main(String[] args) {
+ int cnt = 0;
+ for (int n : new RandomSequence(100)) {
+ System.out.println(String.format("#%d: %d", cnt++, n));
+ }
+ }
+
+ private static class RandomSequence implements Iterable {
+ private int amount;
+
+ public RandomSequence(int amount) {
+ this.amount = amount;
+ }
+
+ @NotNull
+ @Override
+ public Iterator iterator() {
+ return new RandomIterator(amount, 0, 100);
+ }
+ }
+
+
+ private static class RandomIterator implements Iterator {
+ private static Random rnd = new Random();
+ private int amount, a, b;
+
+ public RandomIterator(int amount, int a, int b) {
+ assert b > a;
+ this.amount = amount;
+ this.a = a;
+ this.b = b;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return amount > 0;
+ }
+
+ @Override
+ public Integer next() {
+ --amount;
+ return rnd.nextInt(b - a + 1) + a;
+ }
+ }
+
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/Es_SkipIterator.java b/2019-20/Lezioni/src/esercizi/Es_SkipIterator.java
new file mode 100644
index 0000000..103e7f4
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/Es_SkipIterator.java
@@ -0,0 +1,60 @@
+package esercizi;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class Es_SkipIterator {
+
+ public static class SkipArrayList extends ArrayList {
+ @Override
+ public Iterator iterator() {
+ // senza usare l'iteratore originale
+ return new Iterator() {
+ private int pos = 0;
+ @Override
+ public boolean hasNext() {
+ return pos < size();
+ }
+
+ @Override
+ public T next() {
+ T x = get(pos);
+ pos += 2;
+ return x;
+ }
+ };
+ // usando l'iteratore originale
+ /*Iterator it = super.iterator();
+ return new Iterator() {
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public T next() {
+ T x = it.next();
+ if (it.hasNext()) it.next();
+ return x;
+ }
+ };*/
+ }
+ }
+
+
+ public static void main(String[] args) {
+ List l = new SkipArrayList<>();
+ for (int i = 0; i < 21; ++i)
+ l.add(i);
+
+ Iterator it = l.iterator();
+ while(it.hasNext()) {
+ int n = it.next();
+ System.out.println(n);
+ }
+ }
+
+
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/EsercizioCache.java b/2019-20/Lezioni/src/esercizi/EsercizioCache.java
new file mode 100644
index 0000000..91600e8
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/EsercizioCache.java
@@ -0,0 +1,175 @@
+package esercizi;
+
+import it.unive.dais.po2.myjdk.Pair;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.BiFunction;
+import java.util.function.Supplier;
+
+public class EsercizioCache {
+
+
+ public static Pair cputime(Supplier f) {
+ long now0 = System.nanoTime();
+ T r = f.get();
+ long now1 = System.nanoTime();
+ return new Pair<>(r, now1 - now0);
+ }
+
+ // cache funzionale
+
+ public static class FCache {
+ private final @NotNull BiFunction, K, V> f;
+ @NotNull
+ private final Map m = new HashMap<>();
+
+ public FCache(@NotNull BiFunction, K, V> f) {
+ this.f = f;
+ }
+
+ @NotNull
+ public V lookup(@NotNull K k) {
+ if (m.containsKey(k)) {
+ V r = m.get(k);
+ System.out.println(String.format("hit(%s) = %s", k, r));
+ return r;
+ } else {
+ V v = f.apply(this, k);
+ m.put(k, v);
+ return v;
+ }
+ }
+ }
+
+ // cache astratta
+
+ public static abstract class AbstractCache {
+ @NotNull
+ private final Map m = new HashMap<>();
+
+ protected AbstractCache() {}
+
+ @NotNull
+ protected abstract V onMiss(@NotNull K k);
+
+ @NotNull
+ protected V recur(@NotNull K k) {
+ return lookup(k);
+ }
+
+ @NotNull
+ public V lookup(@NotNull K k) {
+ if (m.containsKey(k)) {
+ V r = m.get(k);
+ System.out.println(String.format("hit(%s) = %s", k, r));
+ return r;
+ } else {
+ V v = onMiss(k);
+ m.put(k, v);
+ return v;
+ }
+ }
+ }
+
+
+
+
+ public static void main(String[] args) {
+ AbstractCache cache1 = new AbstractCache<>() {
+ @NotNull
+ @Override
+ protected Long onMiss(@NotNull Integer n) {
+ return n < 2 ? 1 : recur(n - 1) + recur(n - 2);
+ }
+ };
+
+ }
+
+
+
+ // functional version
+
+ public static long cacheFib(FCache c, int n) {
+ return n < 2 ? 1 : c.lookup(n - 1) + c.lookup(n - 2);
+ }
+
+ public static long slowFib(int n) {
+ return n < 2 ? 1 : slowFib(n - 1) + slowFib(n - 2);
+ }
+
+ public static void main3(String[] args) {
+ final int N = 45;
+
+ // slowFib
+ for (int i = 0; i < N; ++i) {
+ final int n = i;
+ Pair r = cputime(() -> slowFib(n));
+ System.out.println(String.format("slowFib(%d) = %d [%g s]", n, r.first, ((double) r.second / 1000000000.)));
+ }
+ // cacheFib
+ FCache cache1 = new FCache<>(EsercizioCache::cacheFib);
+ for (int i = 0; i < N; ++i) {
+ final int n = i;
+ Pair r = cputime(() -> cache1.lookup(n));
+ System.out.println(String.format("cacheFib(%d) = %d [%g s]", n, r.first, ((double) r.second / 1000000000.)));
+ }
+ }
+
+
+ // versione parametrica
+
+ public static long fastFibRecur(long n, Map cache) {
+ return n < 2 ? 1L : fastFib(n - 1, cache) + fastFib(n - 2, cache);
+ }
+
+ public static long fastFib(long n, Map cache) {
+ if (cache.containsKey(n)) return cache.get(n);
+ else {
+ long r = fastFibRecur(n, cache);
+ cache.put(n, r);
+ return r;
+ }
+ }
+
+ public static class CachedFib {
+ private final Map cache = new HashMap<>();
+
+ private long fibRecur(long n) {
+ return n < 2 ? 1L : fib(n - 1) + fib(n - 2);
+ }
+
+ public long fib(long n) {
+ if (cache.containsKey(n)) return cache.get(n);
+ else {
+ long r = fibRecur(n);
+ cache.put(n, r);
+ return r;
+ }
+ }
+ }
+
+ public static void main2(String[] args) {
+
+ // versione senza oggetto
+ Map m = new HashMap<>();
+ for (int i = 0; i < 100; ++i) {
+ long n = i;
+ Pair r = cputime(() -> fastFib(n, m));
+ System.out.println(String.format("fib(%d) = %d [%g s]", n, r.first, ((double) r.second / 1000000000.)));
+ }
+
+ // versione con oggetto
+ CachedFib cache = new CachedFib();
+ for (int i = 0; i < 100; ++i) {
+ long n = i;
+ Pair r = cputime(() -> cache.fib(n));
+ System.out.println(String.format("fib(%d) = %d [%g s]", n, r.first, ((double) r.second / 1000000000.)));
+ }
+
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/2019-20/Lezioni/src/esercizi/MapIterator.java b/2019-20/Lezioni/src/esercizi/MapIterator.java
new file mode 100644
index 0000000..d6116f2
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/MapIterator.java
@@ -0,0 +1,62 @@
+package esercizi;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+
+public class MapIterator {
+
+
+
+ public static Iterator mapIterator(Iterator it, Function f) {
+ return new Iterator() {
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public B next() {
+ try {
+ A a = it.next();
+ return f.apply(a);
+ }
+ catch (RuntimeException e) {
+ System.err.println(String.format("exception caught: %s", e.getMessage()));
+ if (hasNext()) return next();
+ else throw e;
+ }
+ }
+ };
+ }
+
+
+ public static void main(String[] args) {
+ List l = new ArrayList<>();
+ for (int i = -10; i < 20; ++i) {
+ l.add(i);
+ }
+ Iterator it = mapIterator(l.iterator(), (n) -> (double) n);
+ while (it.hasNext()) {
+ double x = it.next();
+ System.out.println(x);
+ }
+
+ Iterator it2 = mapIterator(l.iterator(),
+ new Function<>() {
+ @Override
+ public Double apply(Integer n) {
+ if (n > 0) return (double) n;
+ else throw new RuntimeException();
+ }
+ });
+ while (it2.hasNext()) {
+ double x = it2.next();
+ System.out.println(x);
+ }
+
+
+ }
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/PO1.java b/2019-20/Lezioni/src/esercizi/PO1.java
new file mode 100644
index 0000000..d7ececb
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/PO1.java
@@ -0,0 +1,127 @@
+package esercizi;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Random;
+
+public class PO1 {
+
+ private static final Random rnd = new Random();
+
+ public static class Dungeon {
+ private final Room[][] rooms;
+ private final int w, h;
+
+ public Dungeon(int w, int h) {
+ rooms = new Room[w][h];
+ this.w = w;
+ this.h = h;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ rooms[x][y] = new Room();
+ }
+ }
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ Room r = rooms[x][y];
+ r.n = getRoom(x, y - 1);
+ r.s = getRoom(x, y + 1);
+ r.o = getRoom(x - 1, y);
+ r.e = getRoom(x + 1, y);
+ }
+ }
+ }
+
+ public Room getRoom(int x, int y) {
+ if (x < 0 || y < 0 || x >= w || y >= h) return null;
+ return rooms[x][y];
+ }
+
+ private void reset() {
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < w; ++x) {
+ rooms[x][y].visited = false;
+ }
+ }
+ }
+
+ public double maxScore(int x, int y) {
+ reset();
+ return visit(getRoom(x, y));
+ }
+
+ private static double visit(@Nullable Room start) {
+ if (start == null || start.visited) return 0.;
+ return start.getScore() + visit(start.n) + visit(start.s) + visit(start.e) + visit(start.o);
+ }
+
+ }
+
+ public static void main(String[] args) {
+ Dungeon dung1 = new Dungeon(3, 3);
+ double score = dung1.maxScore(0, 0);
+ }
+
+
+ public static class Room {
+ @NotNull
+ private final Collection treasures;
+ @Nullable
+ Room n, o, s, e;
+ boolean visited = false;
+
+ public Room(@NotNull Collection treasures) {
+ this(treasures, null, null, null, null);
+ }
+
+ public Room() {
+ this(null, null, null, null);
+ }
+
+ public Room(@NotNull Collection treasures, @Nullable Room n, @Nullable Room o, @Nullable Room s, @Nullable Room e) {
+ this.treasures = treasures;
+ this.n = n;
+ this.o = o;
+ this.s = s;
+ this.e = e;
+ }
+
+ public Room(@Nullable Room n, @Nullable Room o, @Nullable Room s, @Nullable Room e) {
+ Collection ts = new ArrayList<>();
+ for (int i = 0; i < rnd.nextInt(10); ++i)
+ ts.add(new Treasure(rnd.nextInt(10), rnd.nextInt(50), rnd.nextInt(100)));
+ this.treasures = ts;
+ this.n = n;
+ this.o = o;
+ this.s = s;
+ this.e = e;
+ }
+
+ public double getScore() {
+ double r = 0.;
+ for (Treasure t : treasures) {
+ r += t.getValue();
+ }
+ return r;
+ }
+
+ }
+
+ public static class Treasure {
+ private final int gold, silver, bronze;
+
+ public Treasure(int g, int s, int b) {
+ this.gold = g;
+ this.silver = s;
+ this.bronze = b;
+ }
+
+ public double getValue() {
+ return gold * 5. + silver * 2. + bronze;
+ }
+ }
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/ScittoGennaio2019__Pool.java b/2019-20/Lezioni/src/esercizi/ScittoGennaio2019__Pool.java
new file mode 100644
index 0000000..7ec745b
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/ScittoGennaio2019__Pool.java
@@ -0,0 +1,99 @@
+package esercizi;
+
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class ScittoGennaio2019__Pool {
+
+ public interface Pool {
+ void add(T x); // popola la pool con un nuovo elemento
+ R acquire() throws InterruptedException; // acquisisce una risorsa
+ void release(R x); // rilascia una risorsa e la rimette nella pool
+ }
+
+ // a
+ public interface BasicPool extends Pool {}
+
+ // b
+ public static class SimplePool implements BasicPool {
+ private LinkedBlockingQueue q = new LinkedBlockingQueue<>();
+
+ @Override
+ public void add(T x) {
+ q.add(x);
+ }
+
+ @Override
+ public T acquire() throws InterruptedException {
+ return q.take();
+ }
+
+ @Override
+ public void release(T x) {
+ add(x);
+ }
+ }
+
+ // c
+
+ public static class Resource {
+ private final T elem;
+ private final AutoPool pool;
+ public Resource(T x, AutoPool p) {
+ this.elem = x;
+ this.pool = p;
+ }
+
+ public T get() { return elem; }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public void finalize() {
+ release();
+ }
+
+ public void release() {
+ pool.release(this);
+ }
+ }
+
+ public static class AutoPool implements Pool> {
+
+
+ private LinkedBlockingQueue q = new LinkedBlockingQueue<>();
+
+ @Override
+ public void add(T x) {
+ q.add(x);
+ }
+
+ @Override
+ public Resource acquire() throws InterruptedException {
+ return new Resource<>(q.take(), this);
+ }
+
+ @Override
+ public void release(Resource x) {
+ q.add(x.elem);
+ }
+
+ }
+
+ public static void main(String[] args) {
+ AutoPool p = new AutoPool<>();
+ try {
+ Resource x = p.acquire();
+
+ String s = x.get().toLowerCase();
+
+// x.release();
+
+
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+
+ // ..
+
+ }
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/ScrittoGennaio2019.java b/2019-20/Lezioni/src/esercizi/ScrittoGennaio2019.java
new file mode 100644
index 0000000..2a1bccd
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/ScrittoGennaio2019.java
@@ -0,0 +1,75 @@
+package esercizi;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Random;
+
+public class ScrittoGennaio2019 {
+
+ /*1a1*/
+ @FunctionalInterface
+ public interface Function {
+ B apply(A x);
+ }
+
+ /*1a2*/
+ public static Iterator mapIterator(Iterator it, Function f) {
+ return new Iterator<>() {
+ @Override
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ @Override
+ public B next() {
+ return f.apply(it.next());
+ }
+ };
+ }
+
+ /*1b1*/
+ public static class Pair {
+ public final A a;
+ public final B b;
+
+ public Pair(A a, B b) {
+ this.a = a;
+ this.b = b;
+ }
+ }
+
+ /*1b2*/
+ public static Iterator> pairIterator(Iterator it) {
+ return new Iterator<>()/*se non specifico non riesce ad inferire*/ {
+ A last;
+
+ @Override
+ public boolean hasNext() {
+ if (it.hasNext())
+ last = it.next();
+ return it.hasNext();
+ }
+
+ @Override
+ public Pair next() {
+ return new Pair<>(last, it.next());
+ }
+ };
+ }
+
+ /*1c*/
+ public static void main(String[] args) {
+ ArrayList al = new ArrayList<>();
+ Random rnd = new Random();
+ for (int i = 0; i < 10; ++i)
+ al.add(rnd.nextInt(10));
+
+ Iterator> cateti = pairIterator(al.iterator());
+
+ Iterator ipotenuse = mapIterator(cateti, p -> Math.sqrt(p.a * p.a + p.b * p.b));
+
+ while (ipotenuse.hasNext())
+ System.out.println("Ipotenusa " + ipotenuse.next());
+ }
+}
+
diff --git a/2019-20/Lezioni/src/esercizi/ScrittoGennaio2020.java b/2019-20/Lezioni/src/esercizi/ScrittoGennaio2020.java
new file mode 100644
index 0000000..899ac8d
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/ScrittoGennaio2020.java
@@ -0,0 +1,47 @@
+package esercizi;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class ScrittoGennaio2020 {
+
+ public static class Point {
+
+ }
+
+ public interface Solid extends Comparable {
+ double area();
+ double volume();
+ PositionedSolid at(Point origin);
+
+ static int compareBy(Function f, S s1, S s2) {
+ return Double.compare(f.apply(s1), f.apply(s2));
+ }
+ static Comparator comparatorBy(Function f) {
+ return (s1, s2) -> compareBy(f, s1, s2);
+ }
+ default int compareTo(Solid s) {
+ Function f = Solid::volume; // (Solid x) -> x.volume()
+ Supplier g = this::volume; // () -> this.volume()
+ return compareBy(Solid::volume, this, s);
+ }
+ }
+
+ public interface Polyhedron extends Solid {
+ double perimeter();
+ @Override
+ PositionedPolyhedron at(Point origin);
+ }
+
+ public interface PositionedSolid {
+ Point origin();
+ }
+
+ public interface PositionedPolyhedron extends PositionedSolid, Iterable {}
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/ScrittoGiugno2019.java b/2019-20/Lezioni/src/esercizi/ScrittoGiugno2019.java
new file mode 100644
index 0000000..d007bf5
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/ScrittoGiugno2019.java
@@ -0,0 +1,73 @@
+package esercizi;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+public class ScrittoGiugno2019 {
+
+ public static class Node implements Iterable {
+ @NotNull
+ private final T data;
+ @Nullable
+ private final Node left, right;
+
+ public Node(@NotNull T data, @Nullable Node l, @Nullable Node r) {
+ this.data = data;
+ left = l;
+ right = r;
+ }
+
+ public Node(@NotNull T data) {
+ this(data, null, null);
+ }
+
+ public Node(@NotNull T data, @NotNull Node l) {
+ this(data, l, null);
+ }
+
+ private void visit(@NotNull Collection c) {
+ c.add(data);
+ if (left != null) left.visit(c);
+ if (right != null) right.visit(c);
+ }
+
+ @NotNull
+ @Override
+ public Iterator iterator() {
+ Collection r = new ArrayList<>();
+ visit(r);
+ return r.iterator();
+ }
+
+ @Override
+ public String toString() {
+ return String.format("%s(%s %s)",
+ data,
+ left == null ? "_" : left,
+ right == null ? "_" : right);
+ }
+ }
+
+
+ public static void main(String[] args) {
+
+ Node l1 = new Node<>(2, new Node<>(4), new Node<>(5)),
+ r1 = new Node<>(3,
+ new Node<>(6,
+ null,
+ new Node<>(7))),
+ root = new Node<>(1, l1, r1);
+
+
+ for (int i : root) {
+ System.out.println(i);
+ }
+
+ System.out.println(root);
+
+ }
+
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/camporese/Laureando.java b/2019-20/Lezioni/src/esercizi/camporese/Laureando.java
new file mode 100644
index 0000000..c548fcd
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/camporese/Laureando.java
@@ -0,0 +1,32 @@
+package esercizi.camporese;
+
+public class Laureando extends Studente {
+ private int votoDiLaurea;
+
+ public Laureando(String nome, int eta, int classe, int mediaVoti, int votoDiLaurea) {
+ super(nome, eta, classe, mediaVoti);
+ this.votoDiLaurea = votoDiLaurea;
+ }
+
+ public int compareTo(Laureando o) {
+ int diff = votoDiLaurea - o.votoDiLaurea;
+ return diff == 0 ? eta - o.eta : diff;
+ }
+
+ @Override
+ public int compareTo(Persona o) {
+ if (o instanceof Laureando) {
+ return compareTo((Laureando) o);
+ }
+ else return super.compareTo(o);
+ }
+
+ /*
+ if (o instanceof Studente) {
+ Studente other = (Studente) o;
+ int diffClasse = classe - other.classe;
+ return diffClasse == 0 ? eta - other.eta : diffClasse;
+ }
+ else return super.compareTo(o);
+ */
+}
diff --git a/2019-20/Lezioni/src/esercizi/camporese/Persona.java b/2019-20/Lezioni/src/esercizi/camporese/Persona.java
new file mode 100644
index 0000000..7f709ed
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/camporese/Persona.java
@@ -0,0 +1,32 @@
+package esercizi.camporese;
+
+public class Persona implements Comparable, Cloneable {
+ protected final String nome;
+ public final int eta;
+
+ public Persona(Persona p) {
+ this.nome = p.nome;
+ this.eta = p.eta;
+ }
+
+ public Persona(String nome, int eta) {
+ this.nome = nome;
+ this.eta = eta;
+ }
+
+ @Override
+ public int compareTo(Persona other) {
+ return eta - other.eta;
+ }
+
+ @Override
+ public String toString() {
+ return nome + ", " + eta;
+ }
+
+ @Override
+ public Persona clone() {
+ return new Persona(this);
+ }
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/camporese/Studente.java b/2019-20/Lezioni/src/esercizi/camporese/Studente.java
new file mode 100644
index 0000000..aeb88f0
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/camporese/Studente.java
@@ -0,0 +1,50 @@
+package esercizi.camporese;
+
+public class Studente extends Persona {
+
+ private int classe;
+ private final int mediaVoti;
+
+ public Studente(String nome, int eta, int classe, int mediaVoti) {
+ super(nome, eta);
+ this.classe = classe;
+ this.mediaVoti = mediaVoti;
+ }
+
+ public Studente(Studente s) {
+ super(s);
+ this.classe = s.classe;
+ this.mediaVoti = s.mediaVoti;
+ }
+
+ public int getClasse() { return classe; }
+
+ public int getMediaVoti() {
+ return this.mediaVoti;
+ }
+
+ public void prossimoAnno() {
+ ++classe;
+ }
+
+ @Override
+ public int compareTo(Persona o) {
+ if (o instanceof Studente) {
+ Studente other = (Studente) o;
+ int diffClasse = classe - other.classe;
+ return diffClasse == 0 ? eta - other.eta : diffClasse;
+ }
+ else return super.compareTo(o);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + ", " + classe + ", " + mediaVoti;
+ }
+
+ @Override
+ public Studente clone() {
+ return new Studente(this);
+ }
+
+}
diff --git a/2019-20/Lezioni/src/esercizi/camporese/main/Es_Camporese.java b/2019-20/Lezioni/src/esercizi/camporese/main/Es_Camporese.java
new file mode 100644
index 0000000..900006b
--- /dev/null
+++ b/2019-20/Lezioni/src/esercizi/camporese/main/Es_Camporese.java
@@ -0,0 +1,93 @@
+package esercizi.camporese.main;
+
+import esercizi.camporese.Persona;
+import esercizi.camporese.Studente;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+public class Es_Camporese {
+
+ @NotNull
+ public static ArrayList mapFilter(Iterable l, boolean ancheBocciati, Function super A, ? extends B> f) {
+ ArrayList c = new ArrayList<>();
+ for (A a : l)
+ if (ancheBocciati || (((Studente) a).getMediaVoti()) >= 6)
+ c.add(f.apply(a));
+ return c;
+ }
+
+ public static B fold(Iterable l, B zero, BiFunction f) {
+ B acc = zero;
+ for (A a : l)
+ acc = f.apply(a, acc);
+ return acc;
+ }
+
+ public static void printIterable(Iterable l, String str) {
+ System.out.println(str);
+ for (A a : l)
+ System.out.println(a);
+ }
+
+
+ public static void main(String[] args) {
+ ArrayList persone = new ArrayList<>();
+ persone.add(new Persona("Alvise", 43));
+ persone.add(new Persona("Federico", 26));
+ persone.add(new Persona("Stefano", 35));
+ persone.add(new Persona("Matteo", 29));
+ persone.add(new Studente("Francesco", 20, 2, 3));
+
+ /*USA PERSONA::COMPARETO*/
+ Collections.sort(persone);
+ /*USA COMPARE*/
+ /*
+ Collections.sort(persone, (o1, o2) -> o1.età - o2.età );
+ */
+ printIterable(persone, "\nPERSONE ORDINATE PER ETA':\n");
+
+ ArrayList studenti = new ArrayList<>();
+ studenti.add(new Studente("Francesco", 20, 2, 3));
+ studenti.add(new Studente("Andrea", 23, 2, 6));
+ studenti.add(new Studente("Daniele", 22, 3, 5));
+ studenti.add(new Studente("Michele", 21, 2, 7));
+ studenti.add(new Studente("Nicola", 20, 1, 10));
+
+ /*
+ NON PUOI USARE Collections.sort(studenti); SE NON USI I GENERICS SU PERSONA
+ perchè useresti il compareTo di Persona e non quello di Studente
+ siccome Studente estende Persona che implementa Comparable
+ */
+ /*USA STUDENTE::COMPARETO*/
+ //Collections.sort(studenti);
+ /*USA COMPARE*/
+ studenti.sort((o1, o2) -> {
+ int diffAnnoCorso = o1.getClasse() - o2.getClasse();
+ return diffAnnoCorso == 0 ? o1.eta - o2.eta : diffAnnoCorso;
+ });
+ printIterable(studenti, "\nSTUDENTI ORDINATI PER (ANNOCORSO, ETA'):\n");
+
+ ArrayList tuttiVengonoPromossi = mapFilter(studenti, true, (x) ->
+ {
+ Studente daRestituire = x.clone();
+ daRestituire.prossimoAnno();
+ return daRestituire;
+ });
+ printIterable(tuttiVengonoPromossi, "\nSTUDENTI CHE SI SPERA ARRIVINO NELLA NUOVA CLASSE:\n");
+
+ ArrayList studentiPromossi = mapFilter(studenti, false, (x) ->
+ {
+ Studente daRestituire = x.clone();
+ daRestituire.prossimoAnno();
+ return daRestituire;
+ });
+ printIterable(studentiPromossi, "\nSTUDENTI PROMOSSI VERAMENTE:\n");
+
+ System.out.println("\nMEDIA VOTI DELLE PERSONE PROMOSSE: " + fold(tuttiVengonoPromossi, 0, (Studente x, Integer acc) -> acc + x.getMediaVoti()) / tuttiVengonoPromossi.size() + "\n");
+ }
+}
+
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyArrayList.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyArrayList.java
similarity index 79%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/MyArrayList.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyArrayList.java
index d99f9e8..be37c1f 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyArrayList.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyArrayList.java
@@ -1,5 +1,8 @@
package it.unive.dais.po2.myjdk;
+import java.util.Collection;
+
+// TODO: togliere il prefisso My da tutti i nomi dei tipi e mostrare la differenza tra tipi omonimi in package diversi
public class MyArrayList implements MyList {
private Object[] a;
@@ -10,9 +13,19 @@ public MyArrayList() {
this.actualSize = 0;
}
+ public MyArrayList(MyCollection extends T> c) {
+ this();
+ MyIterator extends T> it = c.iterator();
+ while (it.hasNext()) {
+ add(it.next());
+ }
+
+ }
+
@Override
public T get(int i) throws OutOfBoundsException {
- if (i >= actualSize) throw new OutOfBoundsException();
+ if (i >= actualSize)
+ throw new OutOfBoundsException("get: invalid position " + i);
//noinspection unchecked
return (T) a[i];
}
@@ -64,6 +77,8 @@ public void clear() {
this.actualSize = 0;
}
+
+
@Override
public MyIterator iterator() {
return new MyIterator<>() {
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyCollection.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyCollection.java
similarity index 99%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/MyCollection.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyCollection.java
index 069871e..5f5936d 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyCollection.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyCollection.java
@@ -11,4 +11,5 @@ public interface MyCollection extends MyIterable {
default boolean isEmpty() {
return size() == 0;
}
+
}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyHashMap.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyHashMap.java
new file mode 100644
index 0000000..b594fea
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyHashMap.java
@@ -0,0 +1,18 @@
+package it.unive.dais.po2.myjdk;
+
+public class MyHashMap implements MyMap {
+ @Override
+ public V get(K k) throws NotFoundException {
+ return null;
+ }
+
+ @Override
+ public void put(K k, V v) {
+
+ }
+
+ @Override
+ public void clear() {
+
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyHashSet.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyHashSet.java
new file mode 100644
index 0000000..4a19860
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyHashSet.java
@@ -0,0 +1,62 @@
+package it.unive.dais.po2.myjdk;
+
+public class MyHashSet extends MyLinkedSet {
+ private HashFun h;
+
+ public interface HashFun {
+ long hash(E e);
+ }
+
+ private static class DefaultHashFun implements HashFun {
+ @Override
+ public long hash(E e) {
+ return e.hashCode();
+ }
+ }
+
+ private class DefaultHashFun__nonstatic implements HashFun {
+ @Override
+ public long hash(T e) {
+ return e.hashCode();
+ }
+ }
+
+ public MyHashSet(HashFun h) {
+ super();
+ this.h = h;
+ }
+
+
+ public MyHashSet() {
+ super();
+ // lambda syntax
+ this.h = (T x) -> x.hashCode();
+ // method reference syntax
+ this.h = T::hashCode;
+ // anonymous class syntax
+ this.h = new HashFun() {
+ @Override
+ public long hash(T e) {
+ return e.hashCode();
+ }
+ };
+ // non-anonymous instance
+ this.h = new DefaultHashFun();
+ // non-anonymous non-static instance
+ this.h = new DefaultHashFun__nonstatic();
+ }
+
+ @Override
+ public void add(T x) {
+ MyIterator it = iterator();
+ boolean found = false;
+ while (it.hasNext()) {
+ T e = it.next();
+ //if (x.hashCode() == e.hashCode())
+ if (h.hash(x) == h.hash(e))
+ found = true;
+ }
+ if (!found)
+ l.add(x);
+ }
+}
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyHashMap.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyIdentityMap.java
similarity index 57%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/MyHashMap.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyIdentityMap.java
index 1364d87..3bf2765 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyHashMap.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyIdentityMap.java
@@ -1,11 +1,14 @@
package it.unive.dais.po2.myjdk;
-public class MyHashMap implements MyMap {
- private MyArrayList> m;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class MyIdentityMap implements MyMap {
+ private ArrayList> m;
@Override
public V get(K k) throws NotFoundException {
- MyIterator> it = m.iterator();
+ Iterator> it = m.iterator();
while (it.hasNext()) {
Pair p = it.next();
if (p.first.equals(k)) return p.second;
@@ -15,15 +18,20 @@ public V get(K k) throws NotFoundException {
@Override
public void put(K k, V v) {
- MyIterator> it = m.iterator();
+ Iterator> it = m.iterator();
while (it.hasNext()) {
Pair p = it.next();
if (p.first.equals(k)) {
+ // TODO: fare la stessa cosa ma con le coppie immutabili
p.second = v;
return;
}
- // TODO: fare la stessa cosa con le coppie immutabili
}
m.add(new Pair<>(k, v));
}
+
+ @Override
+ public void clear() {
+ m = new ArrayList<>();
+ }
}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyIterable.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyIterable.java
new file mode 100644
index 0000000..1f40cd6
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyIterable.java
@@ -0,0 +1,17 @@
+package it.unive.dais.po2.myjdk;
+
+import java.util.function.Consumer;
+
+public interface MyIterable {
+
+ MyIterator iterator();
+
+ default void forEach(Consumer super T> c) {
+ MyIterator it = this.iterator();
+ while (it.hasNext()) {
+ T x = it.next();
+ c.accept(x);
+ }
+ }
+
+}
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyIterator.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyIterator.java
similarity index 100%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/MyIterator.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyIterator.java
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedList.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedList.java
similarity index 65%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedList.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedList.java
index 67db350..f26d6c9 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedList.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedList.java
@@ -1,8 +1,10 @@
package it.unive.dais.po2.myjdk;
+import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+// TODO: sistemare le possibili eccezioni NullPointerException
public class MyLinkedList implements MyList {
@Override
@@ -10,13 +12,22 @@ public MyIterator iterator() {
return null;
}
+ // TODO: come esercizio provare a rendere questa classe statica in modo che abbia il suo generic; e poi modificare MyLinkedList opportunamente
protected class Node {
+ @Nullable
public T data;
+ @Nullable
public Node next;
- public Node(T data, Node next) {
+
+ public Node(@Nullable T data, @NotNull Node next) {
this.data = data;
this.next = next;
}
+
+ public Node(@Nullable T data) {
+ this.data = data;
+ this.next = null;
+ }
}
@Nullable
@@ -27,18 +38,18 @@ public MyLinkedList() {
}
public void add(T e) {
- head = new Node(e, head);
+ head = head == null ? new Node(e) : new Node(e, head);
}
@Override
public int size() {
int r = 0;
- for (Node n = head; n.next != null; ++r);
+ for (@Nullable Node n = head; n.next != null; ++r);
return r;
}
@Override
- public boolean contains(T x) {
+ public boolean contains(@NotNull T x) {
MyIterator it = iterator();
while (it.hasNext()) {
T e = it.next();
@@ -52,10 +63,11 @@ public void clear() {
head = null;
}
+ @Nullable
public T get(int pos) throws OutOfBoundsException {
Node n = head;
for (; pos > 0; --pos)
- if ((n = head.next) == null) throw new OutOfBoundsException();
+ if ((n = head.next) == null) throw new OutOfBoundsException("get: invalid position " + pos);
return n.data;
}
@@ -64,7 +76,7 @@ public void add(int i, T x) {
int r = 0;
Node n = head;
for (; n.next != null && r < i; ++r);
- n.next = new Node(x, n.next); // TODO: da testare
+ n.next = new Node(x, n.next);
}
@@ -74,16 +86,16 @@ public boolean remove(int i) {
Node n = head;
for (; n.next != null && r < i - 1; ++r);
if (n.next != null) {
- n.next = n.next.next; // TODO: da testare
+ n.next = n.next.next;
}
return true;
}
@Override
public boolean remove(T x) {
- // TODO: da implementare
+ // TODO: da fare per casa
throw new RuntimeException("not implemented");
}
+}
-}
\ No newline at end of file
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedSet.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedSet.java
similarity index 89%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedSet.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedSet.java
index 61bf8c8..daa6da0 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedSet.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyLinkedSet.java
@@ -1,5 +1,6 @@
package it.unive.dais.po2.myjdk;
+// TODO: LinkedSet non è un bel nome, non si capisce: meglio trovarne un'altro
public class MyLinkedSet implements MySet {
protected MyLinkedList l;
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyList.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyList.java
similarity index 100%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/MyList.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyList.java
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyMap.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyMap.java
similarity index 88%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/MyMap.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyMap.java
index 52abf48..5dd0d4d 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MyMap.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MyMap.java
@@ -3,4 +3,5 @@
public interface MyMap {
V get(K k) throws NotFoundException;
void put(K k, V v);
+ void clear();
}
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/MySet.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MySet.java
similarity index 100%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/MySet.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/MySet.java
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/NotFoundException.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/NotFoundException.java
similarity index 100%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/NotFoundException.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/NotFoundException.java
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/OutOfBoundsException.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/OutOfBoundsException.java
similarity index 52%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/OutOfBoundsException.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/OutOfBoundsException.java
index 00c0b9d..46968d8 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/myjdk/OutOfBoundsException.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/OutOfBoundsException.java
@@ -1,5 +1,7 @@
package it.unive.dais.po2.myjdk;
public class OutOfBoundsException extends Exception {
-
+ public OutOfBoundsException(String message) {
+ super(message);
+ }
}
diff --git a/2020/Lezioni/src/it/unive/dais/po2/myjdk/Pair.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/Pair.java
similarity index 99%
rename from 2020/Lezioni/src/it/unive/dais/po2/myjdk/Pair.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/myjdk/Pair.java
index 2ffe513..fa7ce6b 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/myjdk/Pair.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/Pair.java
@@ -9,4 +9,5 @@ public Pair(A a, B b) {
this.first = a;
this.second = b;
}
+
}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/TestList.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/TestList.java
new file mode 100644
index 0000000..cc58492
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/TestList.java
@@ -0,0 +1,18 @@
+package it.unive.dais.po2.myjdk;
+
+public class TestList {
+ public static void main(String[] args) {
+ try {
+ MyList a = new MyArrayList<>();
+ a.add(23);
+ a.add(11);
+
+ int n = a.get(1);
+ System.out.println("elemento in posizione 1: " + n);
+
+ } catch (OutOfBoundsException e) {
+ System.out.println("eccezione: " + e.getMessage());
+ }
+
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/TestMap.java b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/TestMap.java
new file mode 100644
index 0000000..02a93d4
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/myjdk/TestMap.java
@@ -0,0 +1,23 @@
+package it.unive.dais.po2.myjdk;
+
+public class TestMap {
+
+ public static void main(String[] args) {
+ try {
+
+ MyMap m = new MyIdentityMap<>();
+ m.put("alvise", 42);
+ m.put("francesco", 12);
+ m.put("gianni", 56);
+ m.put("pippo", 78);
+
+ int eta_di_gianni = m.get("gianni");
+ System.out.println("risultato: " + eta_di_gianni);
+
+ m.clear();
+
+ } catch (NotFoundException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/other/FilosofiACena__Francesco.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/FilosofiACena__Francesco.java
new file mode 100644
index 0000000..da97db5
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/FilosofiACena__Francesco.java
@@ -0,0 +1,107 @@
+package it.unive.dais.po2.other;
+
+import org.jetbrains.annotations.Nullable;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public class FilosofiACena__Francesco {
+
+ public static class Monitor {
+ @Nullable
+ private static Monitor instance = null;
+
+ private int postiTot;
+ private boolean[] bacchetta;
+
+ private Monitor(int postiTot) {
+ this.postiTot = postiTot;
+ this.bacchetta = new boolean[postiTot];
+ for (int i = 0; i < postiTot; ++i)
+ bacchetta[i] = true;
+ }
+
+ public synchronized void raccogli_sx(int posto) throws InterruptedException {
+ while (!bacchetta[posto])
+ this.wait();
+ bacchetta[posto] = false;
+ }
+
+ public synchronized void raccogli_dx(int posto) throws InterruptedException {
+ raccogli_sx((posto + 1) % postiTot);
+ }
+
+ public synchronized void deposita_sx(int posto) {
+
+ bacchetta[posto] = true;
+ }
+
+ public synchronized void deposita_dx(int posto) {
+ deposita_sx((posto + 1) % postiTot);
+ this.notifyAll();
+ }
+
+ public static synchronized Monitor getInstance(int postiTot) {
+ if (instance == null)
+ instance = new Monitor(postiTot);
+ return instance;
+ }
+ }
+
+ public static void codiceFilosofo(int posto, Monitor tavola) throws InterruptedException {
+ while (true) {
+ /*PENSA*/
+ System.out.println("Filosofo " + posto + " pensa");
+ Thread.sleep(1000);
+ tavola.raccogli_sx(posto);/*raccoglie la bacchetta sinistra*/
+ tavola.raccogli_dx(posto);/*raccoglie la bacchetta destra*/
+ /*MANGIA*/
+ System.out.println("Filosofo " + posto + " mangia");
+ Thread.sleep(1000);
+ tavola.deposita_sx(posto);/*deposita la bacchetta sinistra*/
+ tavola.deposita_dx(posto);/*deposita la bacchetta destra*/
+ }
+ }
+
+ public static class Filosofo extends Thread implements Runnable {
+ private int posto;
+ private Monitor tavola;
+
+ public Filosofo(int posto, Monitor tavola) {
+ this.posto = posto;
+ this.tavola = tavola;
+ }
+
+ @Override
+ public void run() {
+ try {
+ codiceFilosofo(posto, tavola);
+ } catch (InterruptedException ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ int nFilosofi = 5;
+ final Monitor tavola = Monitor.getInstance(5);
+ Collection filosofi = new ArrayList<>();
+ for (int i = 0; i < nFilosofi; ++i) {
+// Filosofo filosofo = new Filosofo(i, tavola);
+ final int[] posto = new int[] { i }; // trucco dell'array final con 1 solo elemento
+
+ Thread filosofo = new Thread(() -> {
+ try {
+ codiceFilosofo(posto[0], tavola);
+ }
+ catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ });
+
+ filosofo.start();
+ filosofi.add(filosofo);
+ }
+ }
+}
+
+
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/other/ForEachTest.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/ForEachTest.java
new file mode 100644
index 0000000..edd96ab
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/ForEachTest.java
@@ -0,0 +1,38 @@
+package it.unive.dais.po2.other;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Consumer;
+
+public class ForEachTest {
+
+ public static class StrangeArrayList extends ArrayList {
+ @Override
+ public void forEach(Consumer super T> c) {
+ System.out.println("ciao");
+ Iterator it = iterator();
+ int cnt = 0;
+ while(it.hasNext() && cnt < 5) {
+ T x = it.next();
+ c.accept(x);
+ ++cnt;
+ }
+ }
+ }
+
+
+ public static void main(String[] args) {
+ List l1 = new StrangeArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l1.add(i);
+ }
+
+ for (Integer n : l1) {
+ System.out.println(n);
+ }
+ l1.forEach(n -> System.out.println(n));
+
+
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/other/FunctionalPrimitives.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/FunctionalPrimitives.java
new file mode 100644
index 0000000..8b300db
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/FunctionalPrimitives.java
@@ -0,0 +1,161 @@
+package it.unive.dais.po2.other;
+
+import it.unive.dais.po2.zoo.Animal;
+import it.unive.dais.po2.zoo.ColoredAnimal;
+import it.unive.dais.po2.zoo.Dog;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.BiFunction;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+public class FunctionalPrimitives {
+
+ public static List map(Iterable l, Function super A, ? extends B> f) {
+ List c = new ArrayList<>();
+ for (A a : l) {
+ B b = f.apply(a);
+ c.add(b);
+ }
+ return c;
+ }
+
+ public static List map2(Iterable l, Function super A, ? extends B> f) {
+ return fold(l, new ArrayList<>(), (x, acc) -> {
+ acc.add(f.apply(x));
+ return acc;
+ });
+ }
+
+ public static void filter__imperative(Iterable l, Function p) {
+ Iterator it = l.iterator();
+ while (it.hasNext()) {
+ A a = it.next();
+ if (!p.apply(a)) it.remove();
+ }
+ }
+
+ public static List filter__pure(Iterable l, Function p) {
+ List r = new ArrayList<>();
+ for (A a : l) {
+ if (p.apply(a)) r.add(a);
+ }
+ return r;
+ }
+
+ public static void iter(Iterable l, Consumer f) {
+ for (A a : l) {
+ f.accept(a);
+ }
+ }
+
+ public static B fold(Iterable l, B zero, BiFunction f) {
+ B acc = zero;
+ for (A a : l) {
+ acc = f.apply(a, acc);
+ }
+ return acc;
+ }
+
+ public static B fold_recur(Iterable l, B zero, BiFunction f) {
+ return fold_recur(l.iterator(), zero, f);
+ }
+
+ // fold : list A -> B -> (A * B -> B) -> B
+ public static B fold_recur(Iterator it, B zero, BiFunction f) {
+ // caso ricorsivo
+ if (it.hasNext()) {
+ return fold_recur(it, f.apply(it.next(), zero), f);
+ }
+ // caso base
+ else {
+ return zero;
+ }
+ // equivalente ma in una solo espressione
+ //return it.hasNext() ? fold_recur(it, f.apply(it.next(), zero), f) : zero;
+ }
+
+ public static void f() { // function_f:
+ int i = 0; // li r0, #0
+ while (i < 10) { // loop:
+ // cmp r0, #10
+ // jeq exit
+ System.out.println("ciao " + i); // call ...
+ i = i + 1; // add r0, #1, r0
+ } // jmp loop
+ // exit:
+ // balbalbla
+ }
+
+ public static void g(int i) { // function_g:
+ if (i > 0) { // ld sp, r0
+ // cmp r0, #0
+ // jeq exit
+ System.out.println("ciao " + i); // call ...
+ g(i - 1); // sub r0, #1
+ // st r0, sp
+ } // jmp function_g
+ // exit:
+ // blablabla
+ }
+
+ @FunctionalInterface
+ interface TriFunction {
+ R apply(A a, B b, C c);
+ }
+
+
+ public static void main(String[] args) {
+
+ g(10); // st #10, sp
+ // jmp function_g
+
+ List l1 = new ArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l1.add(i);
+ }
+ Collection r1 = map(l1, (x) -> x * 2);
+ int sum = fold(r1, 0, (x, acc) -> x + acc);
+
+
+ List l2 = new ArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l2.add(new Dog(i, "red"));
+ }
+ List r2 = map(l2, (ColoredAnimal x) -> new Dog(x.getWeight() - 5, x.getColor()));
+
+ iter(l2, (Dog d) -> System.out.println(d));
+ for (Dog d : l2) System.out.println(d);
+ List> r = map(l2, (Dog d) -> { System.out.println(d); return null; });
+
+
+ String s = "ciao";
+ boolean b = s.isEmpty();
+ Function f = String::isEmpty;
+ Predicate p = String::isEmpty;
+
+ int i = s.indexOf('c');
+ BiFunction g = String::indexOf;
+
+ int j = s.lastIndexOf('c', 8);
+ TriFunction h = String::lastIndexOf;
+
+ {
+ List l = new ArrayList<>();
+ l.add("pippo");
+ l.add("baudo");
+ l.add("pluto");
+ String s2 = String.join(",", l);
+ BiFunction, String> k = String::join;
+ }
+
+ Function id = Function.identity();
+ Function, ?> id2 = (x) -> x; // fun x -> x
+
+ }
+
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/other/FunctionalTest.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/FunctionalTest.java
new file mode 100644
index 0000000..24b3b1a
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/FunctionalTest.java
@@ -0,0 +1,122 @@
+package it.unive.dais.po2.other;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+public class FunctionalTest {
+
+ public static Collection map(Collection l, Function f) {
+ Collection c = new ArrayList<>();
+ for (A a : l) {
+ B b = f.apply(a);
+ c.add(b);
+ }
+ return c;
+ }
+
+ public static void print(Collection c) {
+ map(c, new Function() {
+ @Override
+ public Void apply(X x) {
+ System.out.println(x);
+ return null;
+ }
+ });
+
+ }
+
+ private static class MiaFunzionePerMap implements Function {
+ @Override
+ public Integer apply(Integer x) {
+ return x + 1;
+ }
+ }
+
+
+ public static void main(String[] args) {
+
+ List l = new ArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l.add(i);
+ }
+ print(l);
+
+ // LE 4 FORME DI LAMBDA IN JAVA
+ Function f = x -> x + 1;
+ Function f2 = new Function() {
+ @Override
+ public Integer apply(Integer x) {
+ return x + 1;
+ }
+ };
+
+ Supplier g = () -> {
+ if (l.size() > 4) return 1;
+ else return 2;
+ };
+ Supplier g2 = new Supplier() {
+ @Override
+ public Integer get() {
+ if (l.size() > 4) return 1;
+ else return 2;
+ }
+ };
+
+ Consumer h = (x) -> {
+ for (int i = 0; i < x; ++i)
+ System.out.println(i);
+ };
+ Consumer h2 = new Consumer() {
+ @Override
+ public void accept(Integer x) {
+ for (int i = 0; i < x; ++i)
+ System.out.println(i);
+ }
+ };
+
+ Runnable r = () -> {
+ System.out.println("ciao");
+ };
+ Runnable r2 = new Runnable() {
+ @Override
+ public void run() {
+ System.out.println("ciao");
+ }
+ };
+
+
+ // ESEMPI DI CHIAMATA ALLA map()
+
+ // questa è la stessa cosa fatta con una lambda
+ Collection x1 = map(l, x -> x + 1);
+ // questa è con la classe anonima
+ Collection x2 = map(l, new Function() {
+ @Override
+ public Integer apply(Integer x) {
+ return x + 1;
+ }
+ });
+ // questa terza variante usa direttamente una classe NON-anonima
+ Collection x3 = map(l, new MiaFunzionePerMap());
+
+ print(l);
+
+ /*
+ TRADUZIONE DA ANONYMOUS CLASS A LAMBDA
+ LA LAMBDA E' UNO ZUCCHERO SINTATTICO PER UNA ANONYMOUS CLASS
+ Collection r = map(l, new Function() {
+ @Override
+ public B apply(A x) {
+ BODY;
+ }
+ });
+
+ Collection r = map(l, x -> BODY);
+ */
+
+ }
+}
diff --git a/2020/Lezioni/src/it/unive/dais/po2/other/IteratorTest.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/IteratorTest.java
similarity index 74%
rename from 2020/Lezioni/src/it/unive/dais/po2/other/IteratorTest.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/other/IteratorTest.java
index 919b0b2..c85aefd 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/other/IteratorTest.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/IteratorTest.java
@@ -1,5 +1,7 @@
package it.unive.dais.po2.other;
+import it.unive.dais.po2.myjdk.MyIterator;
+
import java.util.*;
public class IteratorTest {
@@ -19,7 +21,7 @@ public static void sum(Iterable a) {
System.out.println(r);
}
- public static void main(String[] args) {
+ public static void main2(String[] args) {
ArrayList a = new ArrayList<>();
populate(a);
@@ -64,4 +66,27 @@ public void populate() {
}
}
+
+
+
+
+ public static void main(String[] args) {
+
+ List l = new ArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l.add(i);
+ }
+
+ Iterator it = l.iterator();
+ while (it.hasNext()) {
+ int n = it.next();
+ System.out.println(n);
+ }
+
+ for (int n : l) {
+ System.out.println(n);
+ }
+
+ }
+
}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/other/IteratorTest__Mattia.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/IteratorTest__Mattia.java
new file mode 100644
index 0000000..f688b32
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/IteratorTest__Mattia.java
@@ -0,0 +1,83 @@
+package it.unive.dais.po2.other;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+public class IteratorTest__Mattia {
+
+ public static class MyArrayList extends ArrayList { /* eredito tutti i membri di ArrayList */
+
+ public enum IteratorKind {DEFAULT, EVEN, ODD}
+
+ /*
+ * Gli assegnamenti fatti in concomitanza con la dichiarazione dei field,
+ * avvengono prima dell' inizializzazione del costruttore
+ */
+ private IteratorKind kind; /* private field di MyArrayList*/
+
+ /*
+ * Costruttore definito affinchè sia possibile decidere in fase
+ * di creazione dell'oggetto MyArrayList, quale comportamento dovrÃ
+ * avere l'iteratore (nel momento del suo utilizzo)
+ */
+ public MyArrayList(IteratorKind kind) {
+ this.kind = kind;
+ }
+
+ /* Costruttore di default, dichiarato esplicitamente (perchè dichiarato un altro costruttore)*/
+ public MyArrayList() {
+ /* assicura il corretto comportamento del metodo Next,
+ * nel caso in cui non venga definito dall'utente un
+ * comportamento speciale per l'iteratore in caso di costruzione
+ * dell'oggetto MyArrayList
+ */
+ this.kind = IteratorKind.DEFAULT;
+ }
+
+
+ /*
+ * Overrido il metodo iterator dell'interfaccia Iterable (ereditata con ArrayList)
+ * affinchè venga ritornato il mio oggetto Iterator (opportunamente modificato)
+ * al posto dell'Iterator classico (ereditato) di ArrayList*/
+ @NotNull
+ @Override
+ public Iterator iterator() {
+ return new Iterator<>() {
+
+ private int i = 0; /* private field della nuova */
+
+ @Override
+ public boolean hasNext() {
+ return i < size(); /* Zucchero sintattico per: MyArrayList.this.size(); */
+ }
+
+ @Override
+ public T next() {
+ @Nullable T toReturn = null;
+
+ switch (kind) {
+ case DEFAULT:
+ toReturn = get(i++);
+ break;
+ case EVEN:
+ toReturn = get(i++);
+ if (hasNext())/* scarto il prossimo valore solo se questo è presente */
+ get(i++);
+ break;
+ case ODD:
+ get(i++);
+ if (hasNext()) /* scarto il prossimo valore solo se questo è presente */
+ toReturn = get(i++);
+ }
+
+ return toReturn;
+ }
+ };
+
+ }
+
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/other/RevArrayList.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/RevArrayList.java
new file mode 100644
index 0000000..77ca60c
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/RevArrayList.java
@@ -0,0 +1,73 @@
+package it.unive.dais.po2.other;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+public class RevArrayList extends ArrayList {
+ public RevArrayList() {
+ super();
+ }
+
+ public RevArrayList(int cap) {
+ super(cap);
+ }
+
+ public static class RevIterator__static implements Iterator {
+ private List l;
+ private int pos;
+
+ public RevIterator__static(List l) {
+ this.l = l;
+ this.pos = l.size() - 1;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return pos >= 0;
+ }
+
+ @Override
+ public T next() {
+ return l.get(pos--);
+ }
+ }
+
+ private class RevIterator__nonstatic implements Iterator {
+
+ private int pos = RevArrayList.this.size() - 1;
+
+ @Override
+ public boolean hasNext() {
+ return pos >= 0;
+ }
+
+ @Override
+ public T next() {
+ return RevArrayList.this.get(pos--);
+ }
+ }
+
+ @Override
+ public Iterator iterator() {
+ //return new RevIterator(this); // classe globale
+ //return new RevIterator__static(this); // classe nested STATICA
+ //return new RevIterator__nonstatic(); // classe nested NON STATIC
+
+ return new Iterator() { // anonymous class
+ private int pos = size() - 1;
+
+ @Override
+ public boolean hasNext() {
+ return pos >= 0;
+ }
+
+ @Override
+ public T next() {
+ T r = get(pos);
+ pos = pos - 2;
+ return r;
+ }
+ };
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/other/RevIterator.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/RevIterator.java
new file mode 100644
index 0000000..e45cfeb
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/RevIterator.java
@@ -0,0 +1,25 @@
+package it.unive.dais.po2.other;
+
+import java.util.Iterator;
+import java.util.List;
+
+public class RevIterator implements Iterator {
+ private List l;
+ private int pos;
+
+ public RevIterator(List l) {
+ this.l = l;
+ this.pos = l.size() - 1;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return pos >= 0;
+ }
+
+ @Override
+ public T next() {
+ return l.get(pos--);
+ }
+}
+
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/other/RevTest.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/RevTest.java
new file mode 100644
index 0000000..0c6f196
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/RevTest.java
@@ -0,0 +1,23 @@
+package it.unive.dais.po2.other;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+
+public class RevTest {
+
+ public static void main(String[] args) {
+ Collection l = new RevArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l.add(i);
+ }
+
+ Iterator it = l.iterator();
+ while (it.hasNext()) {
+ int n = it.next();
+ System.out.println(n);
+ }
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/other/SortingTest.java b/2019-20/Lezioni/src/it/unive/dais/po2/other/SortingTest.java
new file mode 100644
index 0000000..2558372
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/other/SortingTest.java
@@ -0,0 +1,131 @@
+package it.unive.dais.po2.other;
+
+import it.unive.dais.po2.zoo.Dog;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+public class SortingTest {
+
+
+ private static final String ALPHA_NUMERIC_STRING = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+ public static String randomAlphaNumeric(int count) {
+ StringBuilder builder = new StringBuilder();
+ while (count-- != 0) {
+ int character = (int) (Math.random() * ALPHA_NUMERIC_STRING.length());
+ builder.append(ALPHA_NUMERIC_STRING.charAt(character));
+ }
+ return builder.toString();
+ }
+
+ public static void main(String[] args) {
+ Random rand = new Random();
+ List l = new ArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l.add(rand.nextInt(100));
+ }
+ List l2 = new ArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l2.add(randomAlphaNumeric(10));
+ }
+
+ List l3 = new ArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l3.add(new Dog(rand.nextInt(100), randomAlphaNumeric(5)));
+ }
+
+ List l4 = new ArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l4.add(new Rectangle(rand.nextDouble(), rand.nextDouble()));
+ }
+
+ List l5 = new ArrayList<>();
+ for (int i = 0; i < 10; ++i) {
+ l5.add(new Square(rand.nextDouble() * 10.));
+ }
+
+ System.out.println(l);
+ Collections.sort(l);
+ System.out.println(l);
+
+ System.out.println(l2);
+ Collections.sort(l2);
+ System.out.println(l2);
+
+ System.out.println(l3);
+ Collections.sort(l3);
+ System.out.println(l3);
+
+ System.out.println(l4);
+ Collections.sort(l4, new Comparator() {
+ @Override
+ public int compare(Rectangle o1, Rectangle o2) {
+ return Double.compare(o1.base, o2.base);
+ // confronto a mano tra due double
+ /*if (Math.abs(o1.base - o2.base) <= Double.MIN_VALUE)
+ return 0;
+ else if (o1.base - o2.base > 0.) return 1;
+ else return -1;*/
+ // confronto a mano tra due double con if funzionale
+ // return Math.abs(o1.base - o2.base) <= Double.MIN_VALUE ? 0 : o1.base - o2.base > 0. ? 1 : -1;
+ }
+ });
+ System.out.println(l4);
+ Collections.sort(l4, new Comparator() {
+ @Override
+ public int compare(Rectangle o1, Rectangle o2) {
+ return Double.compare(o1.height, o2.height);
+ }
+ });
+ Collections.sort(l4, (o1, o2) -> Double.compare(o1.height, o2.height));
+ // questo non compila
+ //Collections.sort(l4, (Square s1, Square s2) -> Double.compare(s1.diag(), s2.diag()));
+ System.out.println(l4);
+
+
+ System.out.println(l5);
+ Collections.sort(l5, (Square s1, Square s2) -> Double.compare(s1.diag(), s2.diag()));
+ System.out.println(l5);
+ Collections.sort(l5, (s1, s2) -> Double.compare(s1.area(), s2.area()));
+ System.out.println(l5);
+
+ }
+
+
+ private static class Rectangle {
+ public final double base, height;
+
+ public Rectangle(double b, double h) {
+ this.base = b;
+ this.height = h;
+ }
+
+ public double area() { return base * height; }
+ public double perimeter() { return (base + height) * 2.; }
+
+ @Override
+ public String toString() {
+ return String.format("Rectangle[%g * %g]", base, height);
+ }
+ }
+
+ private static class Square extends Rectangle {
+ public Square(double l) {
+ super(l, l);
+ }
+
+ public double side() { return base; }
+ public double diag() { return side() * Math.sqrt(2.); }
+
+ @Override
+ public String toString() {
+ return String.format("Square[%g]", side());
+ }
+ }
+
+
+ // firme "fake" delle sort
+ static > void sort__(List list) {}
+ static void sort__(List list, Comparator super T> c) {}
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/patterns/ConsumerProducer.java b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/ConsumerProducer.java
new file mode 100644
index 0000000..57ffc57
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/ConsumerProducer.java
@@ -0,0 +1,123 @@
+package it.unive.dais.po2.patterns;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.locks.ReentrantLock;
+
+public class ConsumerProducer {
+
+ private static Random rnd = new Random();
+
+ private static int rand(int a, int b) {
+ return rnd.nextInt(b - a + 1) + a;
+ }
+
+ // se fosse necessario synchronized
+ private static synchronized int rand__sync(int a, int b) {
+ return rnd.nextInt(b - a + 1) + a;
+ }
+
+ // se fosse necessario synchronized: dezuccherata
+ private static synchronized int rand__sync_desugared(int a, int b) {
+ synchronized (ConsumerProducer.class) {
+ return rnd.nextInt(b - a + 1) + a;
+ }
+ }
+
+ // se fosse necessario usare i lock
+ private static int rand__lock(int a, int b) {
+ ReentrantLock l = new ReentrantLock();
+ try {
+ return rnd.nextInt(b - a + 1) + a;
+ } finally {
+ l.unlock();
+ }
+ }
+
+ private static void log(String msg) {
+ Thread self = Thread.currentThread();
+ System.out.println(String.format("%s[%d]: %s", self.getName(), self.getId(), msg));
+ }
+
+ private static Object dummy = new Object();
+
+ public static class Consumer extends Thread {
+ private List l1;
+ private List l2;
+
+ public Consumer(List l1, List l2) {
+ this.l1 = l1;
+ this.l2 = l2;
+ }
+
+ @Override
+ public void run() {
+ while (true) {
+ synchronized (dummy) {
+ if (!l1.isEmpty() && !l2.isEmpty()) {
+ int n1 = l1.remove(0);
+ int n2 = l2.remove(0);
+ log(String.format("Consumer: pop: %d, %d (size: %d, %d) %s %s", n1, n2, l1.size(), l2.size(), l1, l2));
+ }
+ }
+ try {
+ Thread.sleep(rand(1, 50));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ public static class Producer extends Thread {
+ private List l1;
+ private List l2;
+
+ public Producer(List l1, List l2) {
+ this.l1 = l1;
+ this.l2 = l2;
+ }
+
+ private int counter = 0;
+
+ @Override
+ public void run() {
+ while (true) {
+ int n = counter++;
+ synchronized (dummy) {
+ l1.add(n);
+ l2.add(n);
+ log(String.format("Producer: push: %d (size: %d, %d) %s %s", n, l1.size(), l2.size(), l1, l2));
+ }
+ try {
+ Thread.sleep(rand(1, 50));
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+
+ public static void main(String[] args) {
+ try {
+ List l1 = new ArrayList<>();
+ List l2 = new ArrayList<>();
+ Consumer c = new Consumer(l1, l2);
+ Producer p1 = new Producer(l1, l2);
+ Producer p2 = new Producer(l1, l2);
+
+ c.start();
+ p1.start();
+ p2.start();
+
+ c.join();
+ p1.join();
+ p2.join();
+
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/patterns/Singleton.java b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/Singleton.java
new file mode 100644
index 0000000..04deade
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/Singleton.java
@@ -0,0 +1,28 @@
+package it.unive.dais.po2.patterns;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+// verione minimal di un singleton, ma non è riutilizzabile
+
+public class Singleton {
+
+ @Nullable
+ private static Singleton instance = null;
+
+ // fa ciò che fa la cache con una entry
+ @NotNull
+ public static Singleton getInstance() {
+ if (instance == null) {
+ instance = new Singleton();
+ }
+ return instance;
+ }
+
+
+ public static void main(String[] args) {
+ Singleton s = Singleton.getInstance();
+ }
+
+
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/patterns/SyncSingleton.java b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/SyncSingleton.java
new file mode 100644
index 0000000..06fac0c
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/SyncSingleton.java
@@ -0,0 +1,53 @@
+package it.unive.dais.po2.patterns;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class SyncSingleton {
+
+ public static class Display {
+ // eventuali campi privati non-statici
+
+ @Nullable
+ private static Display instance = null;
+
+ private int cnt;
+
+ private Display(int n) {
+ this.cnt = n;
+ // inizializzazione di tutti i tuoi campi privati non-statici
+ }
+
+ // metodi che modificano lo stato
+ public synchronized int getCounter() {
+ return cnt;
+ }
+
+ public synchronized void setCounter(int n) {
+ cnt = n;
+ }
+
+ public synchronized void incrementCounter() {
+ ++cnt;
+ }
+
+ @NotNull
+ public static synchronized Display getInstance(int cnt) {
+ if (instance == null) {
+ instance = new Display(cnt);
+ }
+ synchronized (instance) {
+ instance.cnt *= 3; // esempio di modifica dello stato
+ }
+ return instance;
+ }
+
+ }
+
+ public static void main(String[] args) {
+ Display d = Display.getInstance(50);
+ Display d2 = Display.getInstance(50);
+ }
+
+
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Circle.java b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Circle.java
new file mode 100644
index 0000000..b426049
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Circle.java
@@ -0,0 +1,24 @@
+package it.unive.dais.po2.patterns.factory;
+
+class Circle implements Shape {
+ private final double ray;
+
+ Circle(double ray) {
+ this.ray = ray;
+ }
+
+ @Override
+ public void draw() {
+ System.out.println(String.format("Circle[ray:%g]", ray));
+ }
+
+ @Override
+ public double area() {
+ return Math.PI * ray * ray;
+ }
+
+ @Override
+ public double perimeter() {
+ return Math.PI * 2. * ray;
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Main.java b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Main.java
new file mode 100644
index 0000000..681234c
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Main.java
@@ -0,0 +1,14 @@
+package it.unive.dais.po2.patterns.factory;
+
+public class Main {
+
+ public static void main(String[] args) {
+ try {
+ ShapeFactory factory = new ShapeFactoryWider(4.);
+ Shape shape1 = factory.create("rectangle", 10, 11);
+ Shape shape2 = factory.create("circle", 19);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Rectangle.java b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Rectangle.java
new file mode 100644
index 0000000..1dc7a08
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Rectangle.java
@@ -0,0 +1,26 @@
+package it.unive.dais.po2.patterns.factory;
+
+class Rectangle implements Shape {
+
+ private final double base, height;
+
+ Rectangle(double base, double height) {
+ this.base = base;
+ this.height = height;
+ }
+
+ @Override
+ public void draw() {
+ System.out.println(String.format("Rectangle[%gx%g]", base, height));
+ }
+
+ @Override
+ public double area() {
+ return base * height;
+ }
+
+ @Override
+ public double perimeter() {
+ return (base + height) * 2.;
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Shape.java b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Shape.java
new file mode 100644
index 0000000..e40f9fa
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/Shape.java
@@ -0,0 +1,7 @@
+package it.unive.dais.po2.patterns.factory;
+
+public interface Shape {
+ void draw();
+ double area();
+ double perimeter();
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/ShapeFactory.java b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/ShapeFactory.java
new file mode 100644
index 0000000..018221a
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/ShapeFactory.java
@@ -0,0 +1,17 @@
+package it.unive.dais.po2.patterns.factory;
+
+import org.jetbrains.annotations.NotNull;
+
+public class ShapeFactory {
+
+ @NotNull
+ public Shape create(String name, double... data) throws Exception {
+ if (name.toLowerCase().equals("rectangle"))
+ return new Rectangle(data[0], data[1]);
+ else if (name.toLowerCase().equals("circle"))
+ return new Circle(data[0]);
+ else throw new Exception("invalid shape: " + name);
+ }
+
+
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/ShapeFactoryWider.java b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/ShapeFactoryWider.java
new file mode 100644
index 0000000..f87f514
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/patterns/factory/ShapeFactoryWider.java
@@ -0,0 +1,23 @@
+package it.unive.dais.po2.patterns.factory;
+
+import org.jetbrains.annotations.NotNull;
+
+public class ShapeFactoryWider extends ShapeFactory {
+
+ private final double amp;
+
+ public ShapeFactoryWider(double amp) {
+ this.amp = amp;
+ }
+
+ @Override
+ @NotNull
+ public Shape create(String name, double... data) throws Exception {
+ if (name.toLowerCase().equals("rectangle"))
+ return new Rectangle(data[0] * amp, data[1] * amp);
+ else if (name.toLowerCase().equals("circle"))
+ return new Circle(data[0] * amp);
+ else throw new Exception("invalid shape: " + name);
+ }
+
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/threading/ThreadCreationMain.java b/2019-20/Lezioni/src/it/unive/dais/po2/threading/ThreadCreationMain.java
new file mode 100644
index 0000000..ca05694
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/threading/ThreadCreationMain.java
@@ -0,0 +1,92 @@
+package it.unive.dais.po2.threading;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Random;
+
+public class ThreadCreationMain {
+
+
+ private static void count(String id, long millis, int times) {
+ try {
+ for (int i = 0; i < times; ++i) {
+ System.out.println(id + ": " + i);
+ Thread.sleep(millis);
+ }
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ public static class CounterThread extends Thread {
+ private String name;
+ private long millis;
+ private int times;
+
+ public CounterThread(String name, long millis, int times) {
+ this.name = name;
+ this.millis = millis;
+ this.times = times;
+ }
+
+ @Override
+ public void run() {
+ count(name, millis, times);
+ }
+ }
+
+ private static Random rnd = new Random();
+
+ private static int rand(int a, int b) {
+ return rnd.nextInt(b - a + 1) + a;
+ }
+
+ public static void main(String[] args) {
+
+ Collection threads = new ArrayList<>();
+ for (int i = 0; i < rand(5, 20); ++i) {
+ final String name = String.format("thread#%d", i);
+ final long millis = rand(200, 800);
+ final int times = rand(10, 30);
+
+ // creazione di un thread passando un Runnable al costruttore
+ // Runnable = lambda senza argomenti e senza ritorno
+ Thread t1 = new Thread(() -> {
+ count(name, millis, times);
+ });
+ // stessa cosa ma con la lambda dezuccherata in un Runnable
+ Thread t2 = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ count(name, millis, times);
+ }
+ });
+ // creazione di un thread tramite una anonymous class con override al volo del metodo run
+ Thread t3 = new Thread() {
+ @Override
+ public void run() {
+ count(name, millis, times);
+ }
+ };
+ // creazione di una istanza di CounterThread, cioè di un sottotipo di Thread
+ // e passaggio dei parametri al costruttore
+ Thread t4 = new CounterThread(name, millis, times);
+
+ Thread t = t1;
+ t.start();
+ threads.add(t);
+ }
+
+ // attendo che tutti i thread creati finiscano
+ for (Thread t : threads) {
+ try {
+ t.join();
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ }
+
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Animal.java b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Animal.java
new file mode 100644
index 0000000..02ded64
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Animal.java
@@ -0,0 +1,22 @@
+package it.unive.dais.po2.zoo;
+
+import org.jetbrains.annotations.NotNull;
+
+public class Animal implements Creature, Comparable {
+ protected int weight;
+
+ public Animal(int weight) {
+ this.weight = weight;
+ }
+
+ public int getWeight() { return weight; }
+
+ public void eat(Animal a) {
+ this.weight += a.weight;
+ }
+
+ @Override
+ public int compareTo(@NotNull Animal o) {
+ return this.weight - o.weight;
+ }
+}
diff --git a/2020/Lezioni/src/it/unive/dais/po2/zoo/Cat.java b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Cat.java
similarity index 67%
rename from 2020/Lezioni/src/it/unive/dais/po2/zoo/Cat.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/zoo/Cat.java
index 9b04d47..3852fb5 100644
--- a/2020/Lezioni/src/it/unive/dais/po2/zoo/Cat.java
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Cat.java
@@ -1,10 +1,10 @@
package it.unive.dais.po2.zoo;
-public class Cat extends ColoredAnimal {
+public class Cat extends ColoredAnimal {
- public Cat(int w, String c, Cat p) {
- super(w, c, p);
+ public Cat(int w, String c) {
+ super(w, c);
}
@Override
@@ -13,7 +13,6 @@ public void eat(Animal a) {
color = color + " fat";
}
-
public void meow() {
System.out.println("miao!");
}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/zoo/ColoredAnimal.java b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/ColoredAnimal.java
new file mode 100644
index 0000000..c6c6b1d
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/ColoredAnimal.java
@@ -0,0 +1,13 @@
+package it.unive.dais.po2.zoo;
+
+public abstract class ColoredAnimal extends Animal {
+ protected String color;
+
+ protected ColoredAnimal(int w, String c) {
+ super(w);
+ this.color = c;
+ }
+
+ public String getColor() { return color; }
+
+}
diff --git a/2020/Lezioni/src/it/unive/dais/po2/zoo/Creature.java b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Creature.java
similarity index 100%
rename from 2020/Lezioni/src/it/unive/dais/po2/zoo/Creature.java
rename to 2019-20/Lezioni/src/it/unive/dais/po2/zoo/Creature.java
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Dog.java b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Dog.java
new file mode 100644
index 0000000..d6b02a5
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Dog.java
@@ -0,0 +1,37 @@
+package it.unive.dais.po2.zoo;
+
+import org.jetbrains.annotations.NotNull;
+
+public class Dog extends ColoredAnimal {
+ private int bava;
+
+ public Dog(int w, String c) {
+ super(w, c);
+ bava = w / 10;
+ }
+
+ @Override
+ public void eat(Animal a) {
+ weight += a.weight / 2;
+ }
+
+ public void bark() {
+ System.out.println("bau!");
+ }
+
+ @Override
+ public int compareTo(@NotNull Animal o) {
+ if (o instanceof Dog) {
+ Dog u = (Dog) o;
+ return (this.bava + this.weight) - (o.weight + u.bava);
+ }
+ else {
+ return super.compareTo(o);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Dog[%d, %s]", weight, color);
+ }
+}
diff --git a/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Main.java b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Main.java
new file mode 100644
index 0000000..0377492
--- /dev/null
+++ b/2019-20/Lezioni/src/it/unive/dais/po2/zoo/Main.java
@@ -0,0 +1,70 @@
+package it.unive.dais.po2.zoo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+
+public class Main {
+
+ public static void main(String[] args) {
+ Dog fido = new Dog(15, "bruno");
+ Dog baldo = new Dog(20, "bianco");
+
+ List dogs = new ArrayList<>();
+ dogs.add(fido);
+ dogs.add(baldo);
+
+ /*
+ List