• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours est en vidéo.

Vous pouvez obtenir un certificat de réussite à l'issue de ce cours.

J'ai tout compris !

Mis à jour le 24/04/2019

Utilisez un nouveau type de tableau

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Dans un chapitre du premier cours sur Java, vous avez découvert les tableaux. Nous allons nous intéresser à d'autres outils permettant de stocker plusieurs valeurs, des outils plus polyvalents !

Arraylist

Commençons par un petit rappel sur les tableaux et sur leurs limites.

jshell> int[] ages = new int[10];
ages ==> int[10] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

jshell> ages[9] = 5;
$26 ==> 5

jshell> ages[10] = 16;
| java.lang.ArrayIndexOutOfBoundsException thrown: 10
| at (#27:1)

jshell> for (int i = 0; i < 10; i++) {
 ...> if (ages[i] == 17) {
 ...> System.out.println("17 ans !");
 ...> }
 ...> }

L'inconvénient majeur des tableaux est leur taille prédéfinie.

Deuxième inconvénient : dès lors que l'on veut un comportement avancé, il faut forcément le coder. Il n'y aucune fonctionnalité livrée avec les tableaux.

Les nouveaux types que nous allons voir dans ce chapitre sont des types objets. Ils contiennent donc énormément de fonctionnalités !

Regardons la javadoc d'Arraylist. La partie Method Summary contient les fonctionnalités disponibles. Nous voyons par exemple que l'on peut :

  • ajouter une nouvelle valeur avec  add ;

  • savoir si la liste contient une valeur avec  contains ;

  • supprimer une valeur avec  remove .

Voici un exemple d'utilisation :

jshell> List<String> names = new ArrayList<String>();
names ==> []

jshell> names.add("Romain");
$34 ==> true

jshell> names.add("Julie");
$35 ==> true

jshell> names.add("Sylvain");
$36 ==> true

jshell> names;
names ==> [Romain, Julie, Sylvain]

jshell> names.contains("Julie");
$38 ==> true

jshell> names.remove("Romain");
$39 ==> true

jshell> names
names ==> [Julie, Sylvain]

jshell> names.get(1);
$41 ==> "Sylvain"

jshell> names.indexOf("Julie");
$42 ==> 0

Il est possible de faire énormément de choses avec des  ArrayList  !

Que veux dire <String> ?

Certaines classes peuvent fonctionner avec différents types. Un  ArrayList  peut stocker des  String , mais aussi des  Integer , des  Double  ou pourquoi pas des  Scanner  ! Cela s'appelle des types génériques. 

Pourquoi  names  est de type  List<String> et pas  ArrayList<String> ?

Pour comprendre cette notion, il faut comprendre l'héritage et le polymorphisme. Plusieurs chapitres sont dédiés à ce sujet dans la suite du cours.

HashMap

Pour connaître les  HashMap , commencez par regarder la javadoc. Pour résumer simplement, une HashMap  sert à stocker des couples clé/valeur.  Nous allons utiliser cet outil dans la classe  Bill

Utilisons  HashMap  dans Jshell :

jshell> Map<String, Integer> ages = new HashMap<String, Integer>();
ages ==> {}

jshell> ages.put("Sarah", 22);
$44 ==> null

jshell> ages
ages ==> {Sarah=22}

jshell> ages.put("Paul", 31);
$46 ==> null

jshell> ages.put("Melissa", 45);
$47 ==> null

jshell> ages
ages ==> {Melissa=45, Sarah=22, Paul=31}

jshell> ages.put("Sarah", 23);
$49 ==> 22

jshell> ages
ages ==> {Melissa=45, Sarah=23, Paul=31}

jshell> ages.containsKey("Paul");
$52 ==> true

jshell> ages.get("Paul");
$51 ==> 31

jshell> ages.remove("Melissa");
$53 ==> 45

jshell> ages
ages ==> {Sarah=23, Paul=31}

Je pense que vous avez compris le comportement d'une  HashMap. Pour chaque clé, nous avons une valeur unique. Si nous ajoutons une nouvelle valeur pour une clé qui existe déjà, la valeur précédente est remplacée.

On passe à la facture !

Cette fois-ci, je vous donne l'UML de  Bill. Vous êtes normalement capable de créer la classe.

UML d'une facture
UML d'une facture

Et le code :

package com.cursan.homeshop;

import java.util.Map;

public class Bill {
    private Customer customer;
    private Map<Product, Integer> products;

    /**
     * Add a product with a quantity in the bill
     * @param product product to add
     * @param quantity quantity of the product
     */
    public void addProduct(Product product, Integer quantity) {
        this.products.put(product, quantity);
    }

    public Customer getCustomer() {
        return customer;
    }

    public Map<Product, Integer> getProducts() {
        return products;
    }
}

Pourquoi utilise-t-on  Integer  ici et pas  int  ?

À chaque type primitif correspond un type objet :

  • int  ->  Integer

  • double  ->  Double

  • boolean  ->  Boolean

Ces types objets permettent d'avoir plus de fonctionnalités que les types primitifs. Dans certains cas, vous êtes obligé d'en utiliser. Une  Map  ne peut pas travailler avec des objets primitifs, mais seulement avec des objets.

Pour savoir quand utiliser l'un ou l'autre, c'est simple : utilisez au maximum les types primitifs. Si vous avez besoin de fonctionnalités avancées ou si vous n'avez pas le choix, utilisez les types objets.

Les constructeurs

Vous avez peut-être remarqué quelque chose. Si customer  n'est accessible que via un getter, comment lui donner une valeur ?

Avec les types objets, il y a une notion importante appelée constructeur. Un constructeur, comme son nom l'indique, permet de construire un objet. 

jshell> String texte = new String("ceci est un texte");
texte ==> "ceci est un texte"

Vous le voyez ici, quand on crée une variable de type  String : on peut lui passer un paramètre, comme avec une méthode. En faisant cela, c'est le constructeur de  String  qui est utilisé. 

Voici un constructeur pour  Bill  :

public Bill(Customer customer) {
    this.customer = customer;
}

C'est une méthode sans valeur de retour, qui porte le même nom que sa classe. Il peut très bien y avoir plusieurs constructeurs pour une classe.  String , par exemple, peut être construit avec ou sans chaîne de caractères.

L'UML permet aussi de visualiser les constructeurs :

constructeur de Bill
constructeur de Bill

Voici les UML de  Customer  et de  Product  avec leur constructeur.

UML de Customer
UML de Customer
UML de Product
UML de Product

Le code associé :

package com.cursan.homeshop;

public class Customer {
    private String fullname;
    private String address;

    public Customer(String fullname, String address) {
        this.fullname = fullname;
        this.address = address;
    }

    public String getFullname() {
        return fullname;
    }
    public String getAddress() {
        return address;
    }
}
package com.cursan.homeshop;

public class Product {
    private String name;
    private String description;
    private double price;

    public Product(String name, String description, double price) {
        this.name = name;
        this.description = description;
        this.price = price;
    }

    /**
     * Display a full description of the product
     */
    public void look() {
        System.out.println(String.format(name + " : " + price + "%n" + description));
    }

    /**
     * Add the product to a Bill
     */
    public void buy(Bill bill, Integer quantity) {

    }

    public String getName() {
        return name;
    }

    public String getDescription() {
        return description;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

Nous venons de terminer cette partie. Nous avons commencé à découvrir :

  • la programmation orientée objet en Java

  • la modélisation via les diagrammes de classes UML

  • les visibilités

  • les collections

Dans la prochaine partie, nous irons plus loin avec ces nouveaux concepts et découvrirons des notions avancées de la programmation orientée objet comme l'héritage, le polymorphisme et les interfaces !

Exemple de certificat de réussite
Exemple de certificat de réussite