-
Cours :
- Premiers pas en Java (pdf)
- Classes et objets (pdf)
- Penser objet et encapsulation (pdf)
- Tests et enum (pdf)
- Égalité, final, static, surcharge et documentation (pdf)
- Types paramétrés et interfaces (pdf)
- Agrégation, composition, délégation et extension (pdf)
- Paquetage, accessibilité et exceptions (pdf)
- Final et notions avancées (pdf)
- Documents :
- TP :
TP 1 : Prise en main de Java
Introduction
Ce premier TP va vous permettre de familiariser avec la syntaxe (manière d’écrire) du langage Java via un terminal REPL (Read–Eval–Print Loop) qui est une console interactive.
Environnement de travail
- Si vous êtes sur les machines de l’université, il vous faut choisir l’image Lunix (Linux pour TOUS) en VDI.
- Sur votre machine personnelle, il vous faut un terminal et un JDK à jour :
- Terminal shell si vous êtes sous windows, nous vous conseillons d’installer ubuntu pour avoir accès à un terminal shell. Sous MacOS et linux, un terminal shell est disponible de base. Si vous effectuez ce TP depuis votre machine personnelle, il vous faut installer les outils suivants :
- JDK version 17 ou plus la méthode d’installation dépend de votre système d’exploitation:
- Windows: Téléchargez et exécutez l’Installeur windows
- MacOS: Téléchargez et exécutez l’Installeur MacOS
- Linux: exécutez la commande suivante dans le terminal
sudo apt install openjdk-17-jdk
. Un mot de passe administrateur vous sera demandé.
Java en mode console
Comme pour Python il est possible d’ouvrir une console de type REPL pour le langage Java.
Ouvrez un terminal (Sur les machines de l’université, menu en haut à gauche et choisissez
Menu -> Outils systèmes -> Terminal MATE
) et lancer la commandejshell
. Vous devriez avoir un affichage similaire à celui ci-dessous :~: jshell | Welcome to JShell -- Version 18.0.1.1 | For an introduction type: /help intro jshell>
Types int
et long
(entiers)
Écrivez
a = 3
dans la console (en validant avec un appui sur la touche entrée). Que se passe-t-il ? Comment expliquez-vous cela ?Écrivez
int a
dans la console puis réessayer d’écrirea = 3
Que se passe-t-il ? Comment expliquez-vous cela ? Quelle est la valeur contenue dans la variablea
?Écrivez
int b = 8
dans la console. Que se passe-t-il ?Testez le retour des instructions Java suivantes et donnez le sens des opérateurs
+=
et++
(avant et après une variable) :int c = 0
c += 3
++c
c++
c
Exécuter les deux instructions Java suivantes :
int m = 2147483647
++m
Comment expliquez-vous la valeur retournée par la deuxième instruction ?
Exécuter les deux instructions Java suivantes :
int m = -2147483648
--m
Comment expliquez-vous la valeur retournée par la deuxième instruction ?
Exécuter les deux instructions Java suivantes :
long m = 2147483647
++m
Comment expliquez-vous la valeur retournée par la deuxième instruction ?
Quelle sont les valeurs de
Integer.MAX_VALUE
,Integer.MIN_VALUE
,Long.MAX_VALUE
,Long.MIN_VALUE
?
Types float
et double
(flottants)
Testez l’instruction :
double f = 3
Comment expliquez-vous ce retour ?Testez l’instruction :
double d = 3/6
Comment expliquez-vous ce retour ?Testez l’instruction :
d = 3.0/6
Comment expliquez-vous ce retour ?Testez l’instruction :
int n = 3.0
Que se passe-t-il ?Testez l’instruction :
long l = (long) 3.5
Que se passe-t-il ?Quelle est la valeur de
Math.PI
?Testez l’instruction :
0.1 + 0.1 + 0.1 == 0.3
Comment expliquez-vous ce retour ?
Type boolean
Testez l’instruction :
2 != 3
Comment expliquez-vous ce retour ?Testez l’instruction :
2 == 3
Comment expliquez-vous ce retour ?Testez le retour des instructions Java suivantes et donnez le sens des opérateurs
&&
,||
et!
:boolean t = true
boolean f = false
t && true
t && f
false && f
t || f
t || true
false || f
!t
!f
Définissez un variable entière
x
et affectez-lui la valeur 3. Testez l’instruction :boolean c = (x > 2) && (x < 4)
Comment expliquez-vous ce retour ? Est-ce que la valeur dec
change si vous changez la valeur dex
?Définissez un variable entière
x
et affectez-lui la valeur 3. Testez l’instruction :boolean c = (x >= 3.1) && (x <= 4.1)
Comment expliquez-vous ce retour ?
Type char
Testez les instructions suivantes. Comment expliquez-vous ces retours ?
char c=0
--c
(int) c
Testez les instructions suivantes. Comment expliquez-vous ces retours ?
char ch1 = 'a'
char ch2 = 'b'
char ch3 = 'z'
(int) ch1
(int) ch2
(int) ch3
En déduire une expression valant
true
si une variablech
(qu’il vous faudra créer !) de typechar
contient une lettre de l’alphabet minuscule comprise entre'a'
et'z'
,false
sinon. Est-ce que votre expression esttrue
pour les lettres accentuées comme'é'
?Aller plus loin en proposant une expression qui vaut
true
si une variablech
de typechar
contient une lettre de l’alphabet comprise entre'a'
et'z'
ou'A'
et'Z'
,false
sinon.Soustraire
'A'
à'a'
. Que remarquez-vous ?En déduire une expression qui, étant donné un caractère minuscule contenu dans une variable
ch
, vaut la même lettre en majuscule. Proposer une expression qui effectue l’inverse (étant donné une majuscule, donne une minuscule).Se rendre sur la documentation Java consacrée à la classe
Character
et y trouver les méthodesCharacter.toLowerCase(char ch)
etCharacter.toUpperCase(char ch)
qui permettent de résoudre la question précédente de façon alternative. Dans la suite du cours, on préférera l’utilisation de ces méthodes à la manipulation des indices de caractères. Pourquoi est-il mieux d’utiliser ces méthodes ?
Première compilation en Java
- Créez un fichier
Main.java
ayant le contenu ci-dessous à l’aide d’un éditeur de texte commegedit
.public class Main { public static void main(String[] args) { System.out.println("Hello World"); } }
- Compilez le fichier
Main.java
avec la commandejavac Main.java
Quel fichier a été créé dans le répertoire contenant le fichierMain.java
?
- Exécutez votre programme avec la commande
java Main
Que se passe-t-il ?
- Ajoutez au programme précédent les deux lignes suivantes après l’instruction
System.out.println("Hello World").
, puis compilez-le :for(int index = 0; index < args.length; index++) System.out.println(args[index]);
- Exécutez le programme précédent en ajoutant les mots bonjour, tout, le et monde (séparés par des espaces) à la suite de la commande ; vous taperez donc
java Main bonjour tout le monde
dans le terminal. Que se passe-t-il ? Dans la suite, on appellera arguments du programme les chaîne de caractères bonjour, tout, le et monde.
Tableau en Java
En java, il existe deux types de structures pour stocker des éléments indexés par des entiers :
- les tableaux dont on ne peut pas changer la taille une fois créé (le nombre de cases disponibles reste fixe)
- les listes qui peuvent changer de taille (on peut ajouter de nouvelles cases)
Dans ce TP, nous allons travailler sur les tableaux et nous verrons les listes dans le prochain TP.
Tableaux unidimensionnel
En Java, les tableaux permettent de stocker un nombre prédéfini d’objets d’un même type. Pour déclarer une variable tableau, on doit préciser le type de ses éléments, mais pas le nombre d’éléments qu’il contient : <type elt> [] <nom variable>
.
Exemples :
int[] tab1
boolean[] tab2
- Déclarer une variable de nom
array
pouvant contenir un tableau dedouble
.
La construction d’un tableau se fait en utilisant new
et en précisant sa taille (son nombre d’éléments) : new <type elt> [<taille>]
. C’est une instruction permettant d’obtenir un tableau.
Exemples :
new int[10]
qui construit un tableau pouvant contenir 10 entiers.new boolean[x+3]
qui construit un tableau pouvant contenirx+3
booléens en supposant quex
soit une variable entière.
- Construisez un tableau pouvant contenir 5
double
. Quel est l’affichage produit ? Comment l’expliquez-vous ?
Pour pouvoir réutiliser un tableau, il faut le stocker dans une variable. Cela se fait sans difficulté avec l’opérateur d’affectation =
en mettant à sa gauche une variable de type tableau et à sa droite une instruction de construction de tableau (ou bien une autre variable contenant un tableau).
Exemples :
int[] tab1
puistab1 = new int[10]
(déclaration puis construction et affectation)boolean[] tab2 = new boolean[x+3]
(déclaration, construction et affectation en une seule ligne)
- Construisez un tableau pouvant contenir 5
double
et affectez-le à la variable déjà déclaréarray
.
Les éléments d’un tableau sont numérotés (on dit indexés ou indicés) à partir de 0
. Si nom tab
est un tableau déjà créé, alors on accède à son i-ème élément par : <nom tab>[<expr indice>]
Par exemple si tab
est un tableau de 10 éléments : tab[0]
, … ,tab[9]
sont des expressions correctes, mais tab[10]
est une expression incorrecte (on sort des indices possibles car le tableau est de taille 10).
Il est possible d’affecter les cases du tableau (partie gauche d’une affectation) ou bien d’accéder à leur valeur (par exemple dans la partie droite d’une affectation).
Exemples :
1;
tab[O] = int x = 5;
2] = 4;
tab[x-9] = 10; tab[
- Changez les valeurs contenues dans le tableau
array
pour qu’il contiennent1.1
,2.2
,3.14
,4.2
et100.0
dans cet ordre.
La taille d’un tableau fait partie des attributs fournies par Java : si <nom tab>
est un tableau déjà créé, alors <nom tab>.length
est son nombre d’éléments. Par exemple, tab.length
vaut 10
si tab
est un tableau de 10 éléments.
- Accéder à la taille du tableau
array
et vérifiez qu’elle correspond bien à la valeur donnée lors de sa construction.
- Testez l’instruction
array[5]
. Que se passe-t-il ? Faites de même pour les instructionsarray[-1]
etarray[1.1]
. Que se passe-t-il ?
Il existe des variantes pour la construction de tableau qui permettent d’affecter directement des valeurs dans les cases.
- Testez l’instruction
int[] ints = {1, 2, 3, 4, 5}
Quel est la taille du tableauints
?
- Testez l’instruction
ints = new int[]{1, -2, 4, -8, 16, -32}
Quel est la taille du tableauints
?
- Comment expliquez-vous que la taille dans le tableau contenu dans la variable
ints
a changé ?
- Déclarez une variable
integers
de typeint[]
. Affectez le tableau contenu dans la variableints
dans la variableintegers
. Que se passe-t-il ?
- Déclarez une variable
doubles
de typedouble[]
- Affectez le tableau contenu dans la variable
ints
dans la variabledoubles
. Que se passe-t-il ?
- Déclarer une variable
longs
de typelong[]
(sans construire de tableau). Accéder à la taille de longs et à l’élément d’indice0
. Que se passe-t-il ?
- Déclarer deux variables
floats1
etfloats2
toutes deux de typefloat[]
. Construisez un tableau defloat
de taille10
et affectez-le à la variablefloats1
. Affectez le contenu de la variablefloats1
dans la variablefloats2
.
- Changez la valeur de l’élément d’indice 3 de
floats1
en12.3
. Que se passe-t-il pour l’élément d’indice 3 defloats2
? Comment l’expliquez-vous ?
- Changez la valeur de l’élément d’indice 4 de
floats2
en1.2
. Que se passe-t-il pour l’élément d’indice 4 defloats1
? Comment l’expliquez-vous ?
Tableaux multi-dimensionnels
Un tableau à deux dimensions peut être vu comme un tableau dont chaque élément est lui-même un tableau à une dimension. Et on peut généraliser pour les tableaux à trois (ou plus) dimensions. La déclaration et la construction de tableaux à plusieurs dimensions suivent le schéma des tableaux à une dimension avec <type elt>
qui est un type tableau :
- déclaration :
<type elt> []...[] <nom tab>
(autant de[]
que de dimensions voulues pour le tableau) - construction :
<nom tab> = new <type elt> [<expr nb1>] ... [<expr nbn>];
avec<expr nbi>
la taille voulue pour la \(i\)-ème dimension.
Exemple :
int[][] matrix;
new int[3][2];
matrix = 1][0] = 4;
matrix[int[][] gameBoard = new int [4][4];
Le tableau construit avec new int[3][2]
est un tableau regroupant 3 valeurs (3 cases), chacune contenant un tableau de 2 entiers (2 cases).
Il faut obligatoirement fixer la première dimension à la création. Mais les autres dimensions peuvent être fixées ensuite. Conséquence : un tableau n’est pas forcément rectangulaire.
Exemple :
int [][] brokenGameBoard;
new int[4][];
brokenGameBoard = 0] = new int[4];
brokenGameBoard[1] = new int[3];
brokenGameBoard[
...3] = new int[4]; brokenGameBoard[
- Déclarez une variable
matrix
pouvant contenir un tableau bi-dimensionnel dedouble
.
- Construisez un tableau bi-dimensionnel de
double
de taille \(10\times 8\) et affectez-le à la variablematrix
.
- Changez les valeurs de la case d’indices 3 et 2 de
matrix
et vérifiez que sa valeur a bien changé.
- Est-ce qu’il est possible de changer la valeur de la case d’indices 10 et 0 ou de la case d’indices 0 et 10 de
matrix
?
- Est-ce qu’il est possible de faire en sorte que
matrix[0].length
ait la valeur 10 sans changer le reste de la matrice ?
- Créez un tableau bi-dimensionnel d’entiers (
int
) de sorte qu’il contienne 3 cases : celle d’indice 0 contenant un tableau de taille 3, celle d’indice 1 contenant un tableau de taille 2 et celle d’indice 2 contenant un tableau de taille 1.
Liste en Java
En Java, il est possible de créer une liste d’entiers grâce à l’instruction suivante :
List<Integer> l = new ArrayList<Integer>();
Les listes en Java sont des collections d’objets ordonnés. Nous allons seulement utiliser quelques méthodes de cette classe. Pour plus de détails sur les listes, nous vous conseillons (comme dans la plupart des cas pour Java) de vous référer à la documentation officielle de List
.
Pour cet exercice, nous allons seulement considérer des listes d’Integer
. Integer
est une classe encapsulant le type primitif int
. Cela permet de manipuler des entiers en tant qu’objet, car les int
ne sont pas des objets en Java.
Dans cet exercice, on va utiliser les méthodes suivantes de List
:
add(Integer e)
: ajoute l’entier e à la fin de la listeequals(Object o)
: compare la liste avec l’objeto
et renvoietrue
sio
est une liste contenant les éléments de la liste dans le même ordre.
But de l’exercice
- Comprendre l’utilisation des méthodes de
List
et d’Object
. - Comprendre le concept de référence
Déroulé de l’exercice
Vous devez réaliser les tâches suivantes :
- Lancez la commande jshell dans un terminal (si ce n’est pas déjà fait).
- Définissez et créez une liste
l1
enArrayList<Integer>()
en tapant l’instructionList<Integer> l1 = new ArrayList<>();
- Vérifiez que la liste est bien vide en tapant
l1
. - Ajoutez
1
à la fin de la listel1
à l’aide de la méthodeadd
. - Vérifiez que la liste
l1
contient bien1
en tapantl1
. - Ajoutez
2
à la fin de la listel1
à l’aide de la méthodeadd
. - Vérifiez que la liste
l1
contient bien1
et2
en tapantl1
. - Définissez une liste
l2
en tapant l’instructionList<Integer> l2 = l1
. - Quels sont les entiers contenus dans
l2
? Pourquoil2
contient ces entiers ? - Ajoutez
3
à la fin de la listel1
à l’aide de la méthodeadd
. - Vérifiez le contenu de la liste
l2
. Est-ce qu’il a changé ? - Définissez et créez une liste l3 en tapant l’instruction
List<Integer> l3 = new ArrayList<>();
. - Ajoutez
1
puis2
puis3
à la fin de la listel3
à l’aide de la méthodeadd
. - Vérifiez que la liste
l3
contient bien1
,2
et3
en tapantl3
. - Comparer les listes
l1
etl2
à l’aide de l’opérateur==
en tapantl1 == l2
. - Faites de même pour comparer
l1
etl3
ainsi quel2
etl3
. - Comparer les listes
l1
etl2
à l’aide de la méthodeequals
en tapantl1.equals(l2)
. - Faites de même pour comparer
l1
etl3
ainsi quel2
etl3
. - Comment expliquez-vous le résultat des comparaisons ?
- Arréter jshell en tapant /exit.