pom.xml
(Project Object Model).Consultez http://maven.apache.org/.
Maven télécharge automatiquement tous plugins nécessaires pour son propre fonctionnement ou pour le fonctionnement de votre code.
Les fichiers sont stockés par convention sur $HOME/.m2
. Pour éviter de
surcharger votre répertoire personnel, avant tout, faites un lien symbolique
vers /tmp
:
mkdir /tmp/.m2
ln -s /tmp/.m2 $HOME/.m2
ls -a $HOME
.mvn archetype:generate
suivi des options suivantes:-DgroupId=tc.elp.java.datastructures
(nom de l'organisation, à partir duquel le nom du package est déduit)-DartifactId=Hanoi
(nom du projet)-DarchetypeArtifactId=maven-archetype-quickstart
(crée un pom.xml
par défaut)-DinteractiveMode=false
ls -R
, ainsi que le pom.xml
.App.java
a été créée par défaut. Que fait-elle ?Hanoi
, compilez avec mvn compile
.
Observez la hiérarchie de répertoires avec ls -R
ou tree
.
Où est App.class
?java -cp target/classes/ tc.elp.java.datastructures.App
.mvn clean
?Hanoi
, compilez avec mvn test-compile
.
Observez la hiérarchie de répertoires avec ls -R
ou tree
.
Où est AppTest.class
?mvn test
.Pour utiliser Java 5 (annotations), dans pom.xml
, ajoutez ceci entre
les balises project
:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>5</source>
<target>5</target>
</configuration>
</plugin>
</plugins>
</build>
De plus, pour les tests, corrigez la version de JUnit en 4.2.
A partir de maintenant, sauf mention contraire,
les classes de l'application appartiendront au package tc.elp.java.datastructures
.
Leur fichier source d'extension .java
sera donc ajouté au répertoire
src/main/java/tc/elp/java/datastructures
.
DynamicArray
qui
implémente un tableau d'entiers dynamique auquel on peut ajouter autant
d'entiers qu'on veut à droite (dans les cases de plus grands indices).TestDynamicArray.java
et ajoutez-le au répertoire
src/test/java/tc/elp/java/datastructures
.DynamicArray
§DynamicArray
repose sur un champs de type tableau. L'idée est d'instancier
un tableau dont la longueur est une puissance de 2, en commençant par 1 à la construction.
A chaque fois que la taille de ce tableau est dépassée lors de l'ajout d'un nouvel élément,
un nouveau tableau de taille deux fois plus grande est créé puis utilisé.size
(stocké dans mySize
) désigne le nombre d'éléments mémorisés,
tandis que capacity
désigne la taille du tableau sous-jacent (= myArray.length
):
c'est toujours une puissance de 2.get
retourne l'élément se trouvant à l'indice donné.push
ajoute un nouvel élément à l'indice mySize
quand ce dernier n'est pas donné.Stack
§Stack
composée des méthodes suivantes:boolean empty()
(indique si la pile est vide)int top()
(renvoie l'élément du dessus)void push(int aValue)
(ajoute un élément au-dessus)void pop()
(supprime l'élément du dessus)DynamicArray
précédente.TestStack.java
et ajoutez-le au répertoire
src/test/java/tc/elp/java/datastructures
.top
et pop
sont mal définies
dans le cas d'une pile vide.EmptyStackException
dérivant de java.lang.Exception
,
de façon à ce qu'une exception de ce type soit levée au moment opportun.StackByLinkedList
§StackByLinkedList
.
Bien sûr, elle doit satisfaire l'interface Stack
.classe LinkedListNode
représentant un noeud de liste.StackByArray
§StackByArray
de DynamicArray
,
en veillant à ce que StackByArray
satisfasse l'interface Stack
.L'objectif est maintenant d'implémenter l'algorithme qui déplace les tours de Hanoi; chaque tour étant modélisée par une pile d'entiers.
Bien sûr, vous devez veiller à ce que toute structure de données
de pile (respectant l'interface Stack
) puisse être utilisé dans
votre code.
Ce code sera écrit dans la classe Hanoi
, ajoutée au répertoire
src/main/java
(elle n'appartient pas au package tc.elp.java.datastructures
).
Un fichier .jar
est une archive compressée de classes compilées (fichiers .class
)
Cela facilite donc le déploiement et la diffusion d'un projet.
target/classes
, créez une archive
en tapant jar -cvf monArchive.jar tc/elp/java/datastructures/*
jar -tvf monArchive.jar
.tmp
. Depuis ce répertoire, désarchivez avec jar -xvf ../monArchive.jar
.Hanoi.java
et monArchive.jar
dans le répertoire racine Hanoi
,javac -cp monArchive.jar Hanoi.java
.java -cp monArchive.jar:. Hanoi
. Attention au :.
.:
permet de séparer deux
chemins ou archives jar. Attention l'ordre importe:
l'option -cp doit se trouver avant le fichier à compiler ou la classe à exécuter.Hanoi
, ajoutez à votre archive le fichier
Hanoi.class
et spécifiez un point d'entrée pour la rendre exécutable,
en tapant jar -uvfe monArchive.jar Hanoi Hanoi.class
.NB. L'option e
permet de spécifier la classe à exécuter (= entrypoint).
java -jar monArchive.jar
pour l'exécuter.mvn package
qui génère un jar du projet.jar -uvfe
.Hanoi
.mvn clean
.Hanoi
(et tout ce qu'il contient) dans un répertoire
à vos noms (de la forme NomEtudiant1-NomEtudiant2
).tar.gz
que vous chargerez sur Moodle.Nous avons manipulé jusqu'à maintenant des tableaux et piles d'entiers.
Mais aucune partie du code n'est spécifique au type int
; nous voudrions
donc avoir des structures de données dont on peut choisir le type des éléments.
Depuis Java 5, les generics fournissent un mécanisme pour que les classes, interfaces, méthodes puissent être paramétrées par un type; les incohérences étant détectées à la compilation.
On fait suivre le nom de la classe (ou interface) par le paramètre de type entre chevrons:
class LinkedListNode<E> { ... }
Dans le code, E
représente le type d'un élément:
private E myValue; /// valeur d'un élément
Pour instancier, on donne en argument un type existant:
LinkedListNode<Integer> node = new LinkedListNode<Integer>();
Le mécanisme de substitution est celui du passage de paramètres.
Il n'est pas possible d'avoir un type primitif comme argument:
LinkedListNode<int> node = new LinkedListNode<int>(); //compile pas
En remplacement, on utilise les wrappers Boolean
, Character
,
Integer
, Long
, Float
, and Double
qui héritent tous de Object
(comme tout type non primitif),
et ajoutent des services aux types primitifs (conversion, etc.).
LinkedListNode<Integer> node = new LinkedListNode<Integer>(); //ok
L'objectif de cette partie est de rendre générique l'interface Stack
et les classes LinkedListNode
, StackByLinkedList
(afin d'avoir
des piles dont le type d'élément est arbitraire).
En revanche, comme tableaux et generics cohabitent mal, on exige simplement
de la classe StackByArray
(qui dérive de DynamicArray
) qu'elle satisfasse
l'interface Stack<Integer>
.
Dans les tests et dans Hanoi
, on n'utilisera que des instances de classes
respectant l'interface Stack<Integer>
.
NB. Pour éviter de tout casser, travaillez sur une copie de votre projet.