Blog • code, java

11 idées de projets pour progresser en Java (avec code de solution)

Java reste l'un des langages les plus utilisés au monde. Voici 11 projets concrets, avec code de solution, pour apprendre Java en pratiquant.

Publié le 2 mars 2021 12 min de lecture

Vous voulez devenir développeur Java ? Le langage fait partie de votre cursus scolaire ? Vous cherchez des idées de programmes à réaliser pour étoffer votre portfolio ou tout simplement pour progresser ?

Vous êtes au bon endroit.

Quoi qu'on en dise, Java reste l'un des langages les plus utilisés au monde : applications d'entreprise, Android, systèmes embarqués. La meilleure façon de le maîtriser, c'est de coder de vrais projets plutôt que d'enchaîner les tutoriels passifs.

Voici 11 idées de projets, du plus simple au plus ambitieux, avec le code de solution pour la plupart d'entre eux. Essayez de les faire vous-même avant de regarder la correction, c'est comme ça qu'on progresse vraiment.

1. Un jeu de devinette de nombre

C'est le projet parfait pour débuter : l'ordinateur choisit un nombre aléatoire, l'utilisateur doit le deviner, et le programme indique si sa proposition est trop haute ou trop basse.

import java.util.Random;
import java.util.Scanner;

public class DevinetteNombre {
    public static void main(String[] args) {
        Random random = new Random();
        Scanner scanner = new Scanner(System.in);

        int nombreSecret = random.nextInt(100) + 1; // entre 1 et 100
        int essais = 0;
        int proposition;

        System.out.println("Devinez le nombre entre 1 et 100 !");

        do {
            System.out.print("Votre proposition : ");
            proposition = scanner.nextInt();
            essais++;

            if (proposition < nombreSecret) {
                System.out.println("C'est plus grand !");
            } else if (proposition > nombreSecret) {
                System.out.println("C'est plus petit !");
            } else {
                System.out.println("Bravo, trouvé en " + essais + " essais !");
            }
        } while (proposition != nombreSecret);

        scanner.close();
    }
}

Pour aller plus loin : limitez le nombre d'essais, ou ajoutez des niveaux de difficulté (plage de nombres plus ou moins grande).

2. Un simulateur de lancer de dés

Un mini-projet idéal pour manipuler les nombres aléatoires et les boucles. Simulez le lancer d'un ou plusieurs dés, et affichez des statistiques.

import java.util.Random;

public class LancerDes {
    public static void main(String[] args) {
        Random random = new Random();
        int nombreLancers = 10000;
        int[] resultats = new int[7]; // index 1 à 6 utilisés

        for (int i = 0; i < nombreLancers; i++) {
            int de = random.nextInt(6) + 1;
            resultats[de]++;
        }

        for (int face = 1; face <= 6; face++) {
            double pourcentage = (resultats[face] * 100.0) / nombreLancers;
            System.out.printf("Face %d : %d fois (%.2f%%)%n", face, resultats[face], pourcentage);
        }
    }
}

Pour aller plus loin : simulez un lancer de deux dés et calculez la probabilité de chaque somme (2 à 12), ou ajoutez une interface graphique.

3. Un convertisseur d'unités

Java propose de nombreuses bibliothèques mathématiques et scientifiques. C'est l'occasion parfaite de les utiliser pour développer un convertisseur d'unités.

import java.util.Scanner;

public class ConvertisseurUnites {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("Convertisseur d'unités");
        System.out.println("1. Kilomètres -> Miles");
        System.out.println("2. Celsius -> Fahrenheit");
        System.out.println("3. Kilogrammes -> Pounds");
        System.out.print("Choix : ");
        int choix = scanner.nextInt();

        System.out.print("Valeur à convertir : ");
        double valeur = scanner.nextDouble();
        double resultat;

        switch (choix) {
            case 1:
                resultat = valeur * 0.621371;
                System.out.printf("%.2f km = %.2f miles%n", valeur, resultat);
                break;
            case 2:
                resultat = (valeur * 9.0 / 5.0) + 32;
                System.out.printf("%.2f°C = %.2f°F%n", valeur, resultat);
                break;
            case 3:
                resultat = valeur * 2.20462;
                System.out.printf("%.2f kg = %.2f lbs%n", valeur, resultat);
                break;
            default:
                System.out.println("Choix invalide.");
        }

        scanner.close();
    }
}

Pour aller plus loin : ajoutez une interface graphique avec Swing ou JavaFX, ou gérez davantage de catégories d'unités (longueur, volume, vitesse).

4. Un chronomètre

Pour se familiariser avec les packages de gestion du temps en Java, créer un chronomètre en console est un excellent mini-projet.

import java.util.Timer;
import java.util.TimerTask;

class MyTask extends TimerTask {
    // Le temps de votre chronomètre, ici 5 minutes (300 secondes)
    public static int time = 300;

    public void run() {
        int minutes = (time % 3600) / 60;
        int seconds = time % 60;

        String timeString = String.format("%02d:%02d", minutes, seconds);
        System.out.println(timeString);

        time--;

        // On quitte proprement le programme après la fin du timer
        if (time < 0) System.exit(0);
    }
}

public class Chronometre {
    public static void main(String[] args) {
        MyTask task = new MyTask();
        Timer timer = new Timer();

        // On exécute la tâche toutes les secondes (1000), sans attendre (0)
        timer.schedule(task, 0, 1000);
    }
}

Pour aller plus loin : ajoutez des fonctions timer, réveil, ou la conversion de fuseaux horaires.

5. Un jeu du morpion

Java se porte très bien en matière de jeux vidéo, Minecraft, par exemple, a été codé en Java. Un morpion (tic-tac-toe) en console est un excellent premier projet de jeu.

import java.util.Scanner;

public class Morpion {
    static char[][] grille = new char[3][3];

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        initGrille();
        char joueur = 'X';
        boolean fini = false;

        while (!fini) {
            afficherGrille();
            System.out.println("Joueur " + joueur + ", entrez ligne et colonne (0-2, séparés par un espace) : ");
            int ligne = scanner.nextInt();
            int colonne = scanner.nextInt();

            if (grille[ligne][colonne] != '-') {
                System.out.println("Case déjà prise, réessayez.");
                continue;
            }

            grille[ligne][colonne] = joueur;

            if (verifierVictoire(joueur)) {
                afficherGrille();
                System.out.println("Le joueur " + joueur + " a gagné !");
                fini = true;
            } else if (grillePleine()) {
                afficherGrille();
                System.out.println("Match nul !");
                fini = true;
            }

            joueur = (joueur == 'X') ? 'O' : 'X';
        }

        scanner.close();
    }

    static void initGrille() {
        for (int i = 0; i < 3; i++)
            for (int j = 0; j < 3; j++)
                grille[i][j] = '-';
    }

    static void afficherGrille() {
        for (char[] ligne : grille) {
            for (char c : ligne) System.out.print(c + " ");
            System.out.println();
        }
    }

    static boolean grillePleine() {
        for (char[] ligne : grille)
            for (char c : ligne)
                if (c == '-') return false;
        return true;
    }

    static boolean verifierVictoire(char joueur) {
        for (int i = 0; i < 3; i++) {
            if (grille[i][0] == joueur && grille[i][1] == joueur && grille[i][2] == joueur) return true;
            if (grille[0][i] == joueur && grille[1][i] == joueur && grille[2][i] == joueur) return true;
        }
        if (grille[0][0] == joueur && grille[1][1] == joueur && grille[2][2] == joueur) return true;
        if (grille[0][2] == joueur && grille[1][1] == joueur && grille[2][0] == joueur) return true;
        return false;
    }
}

Pour aller plus loin : ajoutez une interface graphique avec Swing, un mode contre l'ordinateur avec une IA simple, ou même un mode multijoueur en réseau.

6. Un jeu du pendu

Le jeu du pendu est un classique pour pratiquer la manipulation de chaînes de caractères en Java.

import java.util.Scanner;

public class Pendu {
    public static void main(String[] args) {
        String[] mots = {"java", "programmation", "ordinateur", "clavier"};
        String motSecret = mots[(int) (Math.random() * mots.length)];
        char[] motAffiche = new char[motSecret.length()];
        java.util.Arrays.fill(motAffiche, '_');

        int essaisRestants = 6;
        Scanner scanner = new Scanner(System.in);

        while (essaisRestants > 0 && new String(motAffiche).contains("_")) {
            System.out.println("Mot : " + new String(motAffiche));
            System.out.println("Essais restants : " + essaisRestants);
            System.out.print("Proposez une lettre : ");
            char lettre = scanner.next().toLowerCase().charAt(0);

            if (motSecret.indexOf(lettre) >= 0) {
                for (int i = 0; i < motSecret.length(); i++) {
                    if (motSecret.charAt(i) == lettre) {
                        motAffiche[i] = lettre;
                    }
                }
            } else {
                essaisRestants--;
                System.out.println("Lettre incorrecte !");
            }
        }

        if (new String(motAffiche).equals(motSecret)) {
            System.out.println("Bravo, vous avez trouvé : " + motSecret);
        } else {
            System.out.println("Perdu ! Le mot était : " + motSecret);
        }

        scanner.close();
    }
}

Pour aller plus loin : ajoutez des catégories de mots, un système de score, ou une interface graphique affichant le pendu qui se dessine progressivement.

7. Un générateur de mot de passe aléatoire

Un projet court et très pratique pour manipuler des chaînes de caractères et des boucles.

import java.security.SecureRandom;

public class GenerateurMotDePasse {
    public static void main(String[] args) {
        String caracteres = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*";
        int longueur = 12;
        SecureRandom random = new SecureRandom();
        StringBuilder motDePasse = new StringBuilder();

        for (int i = 0; i < longueur; i++) {
            int index = random.nextInt(caracteres.length());
            motDePasse.append(caracteres.charAt(index));
        }

        System.out.println("Mot de passe généré : " + motDePasse);
    }
}

Pour aller plus loin : demandez à l'utilisateur la longueur souhaitée et les types de caractères à inclure (majuscules, chiffres, symboles).

8. Un gestionnaire de bibliothèque en ligne de commande

Un excellent exercice pour pratiquer la programmation orientée objet : modéliser des classes comme Livre et Bibliotheque, et gérer les relations entre elles.

import java.util.ArrayList;
import java.util.List;

class Livre {
    String titre;
    String auteur;
    boolean emprunte;

    Livre(String titre, String auteur) {
        this.titre = titre;
        this.auteur = auteur;
        this.emprunte = false;
    }
}

class Bibliotheque {
    private List<Livre> livres = new ArrayList<>();

    void ajouterLivre(String titre, String auteur) {
        livres.add(new Livre(titre, auteur));
        System.out.println(titre + " a été ajouté.");
    }

    void emprunter(String titre) {
        for (Livre livre : livres) {
            if (livre.titre.equalsIgnoreCase(titre) && !livre.emprunte) {
                livre.emprunte = true;
                System.out.println(titre + " a été emprunté.");
                return;
            }
        }
        System.out.println("Livre indisponible.");
    }

    void rendre(String titre) {
        for (Livre livre : livres) {
            if (livre.titre.equalsIgnoreCase(titre) && livre.emprunte) {
                livre.emprunte = false;
                System.out.println(titre + " a été rendu.");
                return;
            }
        }
    }

    void afficherCatalogue() {
        for (Livre livre : livres) {
            String statut = livre.emprunte ? "Emprunté" : "Disponible";
            System.out.println(livre.titre + " - " + livre.auteur + " (" + statut + ")");
        }
    }
}

public class GestionnaireBibliotheque {
    public static void main(String[] args) {
        Bibliotheque biblio = new Bibliotheque();
        biblio.ajouterLivre("1984", "George Orwell");
        biblio.ajouterLivre("Le Petit Prince", "Antoine de Saint-Exupéry");

        biblio.emprunter("1984");
        biblio.afficherCatalogue();
        biblio.rendre("1984");
        biblio.afficherCatalogue();
    }
}

Pour aller plus loin : ajoutez une persistance des données dans un fichier ou une base de données, et une interface graphique.

9. Une calculatrice avec Swing

Swing est une bibliothèque Java pour construire des interfaces graphiques (GUI). Ce projet est parfait pour apprendre à gérer les événements utilisateur.

Le code complet d'une calculatrice graphique (gestion des boutons, du clavier, des opérations) dépasse largement la centaine de lignes une fois les cas particuliers gérés (division par zéro, chaînage d'opérations, effacement...). Je ne le mets pas en entier ici, mais voici la structure de base pour démarrer :

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionListener;

public class Calculatrice extends JFrame {
    private JTextField ecran;

    public Calculatrice() {
        setTitle("Calculatrice");
        setSize(300, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        ecran = new JTextField();
        ecran.setEditable(false);
        add(ecran, BorderLayout.NORTH);

        JPanel boutons = new JPanel(new GridLayout(4, 4));
        String[] labels = {"7", "8", "9", "/", "4", "5", "6", "*", "1", "2", "3", "-", "0", "=", "+", "C"};

        for (String label : labels) {
            JButton bouton = new JButton(label);
            // C'est ici que vous ajouterez la logique de calcul,
            // en écoutant les clics avec un ActionListener
            boutons.add(bouton);
        }

        add(boutons, BorderLayout.CENTER);
    }

    public static void main(String[] args) {
        new Calculatrice().setVisible(true);
    }
}

À vous de jouer : ajoutez un ActionListener sur chaque bouton pour construire l'expression et l'évaluer. C'est en résolvant ce genre de blocage par vous-même qu'on apprend le mieux.

10. Un client météo

Connectez-vous à une API météo publique (comme OpenWeatherMap) pour afficher la météo d'une ville saisie par l'utilisateur.

Ce projet nécessite une clé d'API personnelle et une bibliothèque de parsing JSON (comme org.json), donc le code complet dépend de votre configuration (gestionnaire de dépendances Maven ou Gradle, clé API...). Voici la structure de la requête HTTP, à adapter :

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

public class ClientMeteo {
    public static void main(String[] args) throws Exception {
        String ville = "Paris";
        String cleApi = "VOTRE_CLE_API"; // à récupérer sur openweathermap.org
        String url = "https://api.openweathermap.org/data/2.5/weather?q=" + ville
                + "&appid=" + cleApi + "&units=metric&lang=fr";

        HttpClient client = HttpClient.newHttpClient();
        HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

        // La réponse est en JSON, il faut ensuite la parser
        // (avec org.json, Gson ou Jackson) pour extraire température, description, etc.
        System.out.println(response.body());
    }
}

Pour aller plus loin : parsez le JSON pour n'afficher que les infos utiles, ajoutez une interface graphique avec des icônes météo, ou un historique des recherches.

11. Une To-Do List Android

Découvrez le développement Android en Java avec le SDK Android. L'application doit permettre d'ajouter des tâches via un champ de texte, et de les marquer comme faites, les supprimer ou les modifier.

Ce projet demande un vrai projet Android Studio (fichiers de layout XML, Activity, RecyclerView, gestion du cycle de vie...). Le code ne tient pas dans un seul fichier ni dans quelques dizaines de lignes, donc je ne le détaille pas ici. Si ce projet vous intéresse, la documentation officielle Android sur les RecyclerView et les ListAdapter est un excellent point de départ.

Pour aller plus loin : ajoutez une sauvegarde locale des tâches avec SQLite ou Room, pour que la liste persiste après la fermeture de l'application.

Comment progresser plus vite en Java

Ces 11 projets vous donnent de quoi pratiquer sérieusement et construire un portfolio solide. Mais avancer seul, sans retour ni structure, peut vite devenir frustrant : on bloque sur une erreur, on ne sait pas si son code est "propre", on perd du temps à configurer son environnement.

Si vous voulez apprendre Java de façon structurée, avec des exercices pratiques corrigés, un éditeur de code intégré et une validation automatique directement dans le navigateur (sans rien installer), j'ai créé un cours pensé pour ça : Java pour débutants sur commentcoder.com.

Les deux premiers chapitres sont gratuits, c'est l'occasion de voir si la pédagogie vous convient avant de vous lancer.

👉 Découvrir le cours Java pour débutants

Les lecteurs de cet article ont aussi aimé

À découvrir

Apprenez à coder par la pratique

Sur CommentCoder, chaque notion est mise en pratique tout de suite : exercices corrigés automatiquement, parcours guidés et progression à votre rythme, dans le navigateur.

Exercices interactifsCorrection automatiqueMode normal et mobile
Voir les cours
Thomas Collart

Thomas Collart, développeur et formateur depuis plus de 20 ans. J'ai formé 3 700 étudiants à travers mes formations en ligne, cumule plus de 2 700 000 vues et 56 700 abonnés sur YouTube, TikTok et Instagram.