Vous souhaitez vous orienter dans un métier qui requiert la maîtrise d’un langage de programmation comme les métiers du Big Data ? Alors vous savez que la programmation informatique n’est pas une compétence optionnelle pour vous.

Dans les métiers de la data, l’un des langages prédominants après scala c’est le langage Java. La majorité des technologies du Big Data sont écrites en Java. L’exemple le plus illustratif est le framework open source Hadoop, destiné à faciliter la création d’applications data distribuées et scalables qui s’exécutent sur des milliers de nœuds d’un cluster. On pourrait également citer le framework Kafka, utilisé pour développer des applications streaming et temps réel.

Java est le choix privilégié pour le développement d’applications Big Data en raison de ses vastes bibliothèques open source bien fournies, d’une documentation abondante, ainsi que d’une communauté mature de programmeurs expérimentés.

Java dispose également d’un certain nombre de packages utiles pour le traitement des données et le calcul scientifique, ce qui le rend bien adapté aux applications de la science des données. D’ailleurs, même le langage Scala qui a plus de cote actuellement sur le marché du Big Data, a été conçu sur Java.

Vous voyez que si vous souhaitez travailler dans le Big Data, vous serez en permanence confrontés au java, d’une façon ou d’une autre. Vous ne pouvez donc pas vous permettre de l’ignorer.

Dans ce guide complet, nous allons vous apprendre toutes les bases de la programmation en Java. L’objectif n’est pas de faire de vous des développeurs Java ou des geeks, mais de vous montrer l’essentiel dont vous avez besoin pour exprimer des problématiques Data en utilisant le langage java.

Qu’est ce que le langage Java et à quoi sert-il ?

Java est un langage de programmation multiplateforme créé en 1995 par James Gosling chez Sun Microsystems (qui apparient aujourd’hui à l’entreprise Oracle). Avant son nom actuel, le langage de programmation a d’abord été appelé « OAK », d’après un chêne qui se trouvait à l’extérieur du bureau de James Gosling.

Une des particularités principales qui différencie le langage Java des autres langages comme le C ou le C++ est la manière dont il est exécuté et compilé sur une machine. Le compilateur Java, nommé javac, ne traduit pas directement le code source en langage machine comme les autres compilateurs. Il le traduit en un langage intermédiaire appelé bytecode. Ce bytecode est ensuite interprété par un autre programme : la machine virtuelle java ou JVM (pour Java Virtual Machine en anglais).

Ainsi, un programme java sera toujours représenté par deux types de fichiers : les fichiers sources en java (extension. java) et le résultat de leur compilation en byte code (fichier d’extension .class).

La JVM est dépendante de la plate-forme, c’est-à-dire que sa mise en œuvre diffère d’une plate-forme à l’autre (comme Windows, Linux, Mac, etc…), mais toutes les JVM peuvent exécuter le même bytecode java : c’est l’approche “write once and run anywhere“, en français “exécuter une fois et écrire partout“.

Grâce à ce système, Java peut être développé sur n’importe quel appareil, n’importe quel système d’exploitation (OS), compilé en un bytecode standard et fonctionner sur n’importe quel appareil équipé d’une JVM. La figure suivante illustre parfaitement cela.

processus de compilation du code java
Figure : processus de compilation du code java

Quelques cas d’utilisation du langage Java

Selon Oracle, plus de 3 milliards de dispositifs utilisent Java, et la plupart des grandes entreprises utilisent Java d’une manière ou d’une autre. Java est utilisé dans un grand nombre de domaines, depuis les applications scientifiques comme les simulateurs de physique, jusqu’aux applications financières comme les sites Web de e-commerce.

De grandes entreprises comme Google, Microsoft et bien d’autres utilisent également Java à de nombreuses fins. Voici quelques utilisations du langage JAVA

  • Développement web : les applications Web sont des applications délocalisées qui fonctionnent sur une architecture client/serveur à 2 tiers minimum. Elles sont très pratiques pour les entreprises, qui peuvent les mettre à jour et les maintenir sans avoir à installer de logiciels sur les ordinateurs clients. Les technologies Java impliquées dans le développement d’applications web sont Java Enterprise Edition (JEE), Java Standard Edition (JSE), JavaServer Pages Standard Tag Library (JSTL), JavaServer Pages (JSP), etc. L’entreprise de développement Java met en œuvre ces technologies pour créer des applications Web attrayantes et sécurisées pour les clients.
  • Développement Android/iOS : les applications Android de Google, ainsi que l’OS lui-même, sont écrits en utilisant Java. D’ailleurs, l’API Android de Google est très similaire au kit de développement Java (JDK). Bien que les applications Android utilisent une JVM différente, le code est toujours écrit en Java.
  • Finance & e-commerce : de nombreux sites Web d’ e-commerce, ainsi que des applications Web destinées aux administrations, à la santé, aux assurances, à l’éducation et à la défense sont construits en Java, ce qui rend les programmeurs Java précieux dans un grand nombre de secteurs.   La mise en œuvre de Java en fait un langage sécurisé, ce qui est important pour les sites Web de e-commerce qui traitent de grandes quantités de données sensibles comme les numéros de carte de crédit et les adresses des utilisateurs.
  • Big Data : comme nous vous l’avons dit en introduction, la majorité des frameworks de calcul distribués sont développés directement ou indirectement en Java. Même le Scala qui est très utilisé dans le domaine, est basé sur Java. Java est donc incontournable en Big Data.
  • Jeux vidéos : la plupart des jeux vidéos sont écrits en Java. Des jeux populaires comme Minecraft sont conçus en Java. Les jeux utilisent des concepts fondamentaux  de Java comme la programmation orientée objet (POO) et le multithreading (l’exécution simultanée de deux ou plusieurs processus, avec l’utilisation la plus efficace du CPU).

Pourquoi devriez-vous apprendre à programmer en Java ?

Quelles sont les principales raisons pour lesquelles il est essentiel à notre époque d’apprendre à programmer en java ? Nous allons vous donner la réponse à cette question ici.

Déjà, pour tous les profils, spécialement les profils de Data Engineer, la pratique de la programmation Java est incontournable dans l’exercice de leur métier.

Voici les nombreux points forts de java, qui font de lui le langage de référence pour développer des applications Big Data :

  • Java est facile à prendre en main :  C’est un langage de  haut niveau, c’est à dire  fait abstraction des caractéristiques techniques du matériel utilisé pour exécuter le programme, tels que la mémoire, et le processeur.
  • Java est un langage de programmation objet et fortement typé : contraignants pendant le développement, l’approche objet et le typage fort du langage Java rendent plus robuste un programme Java dès sa conception.
  • Java a une syntaxe   proche   du   C   et C++ :   en   reprenant   une grande  partie  de  la  syntaxe  de  ces  deux  langages, Java  est vite pris en main par les développeur C et C++.
  • Gestion de la mémoire simplifiée : le garbage  collector,  en français  ramasse-miettes intégré  à  Java  détecte automatiquement  les  objets  inutilisés  pour  libérer  la mémoire qu’ils occupent.
  • Multithreading :  grâce  aux  threads, Java  permet  de  programmer  l’exécution  simultanée  de  plusieurs  traitements et la synchronisation des traitements   qui partagent des informations.
  • Gestion  des  exceptions :  Java l’intègre  autant  pour faciliter  la  mise  au  point  des  programmes  (détection et  localisation  des  bogues)  que  pour  rendre  un  programme plus robuste.
  • Système  de  sécurité :  la plate-forme Java est conçue avec des fonctions de sécurité intégrées au langage et au système d’exécution, telles que la vérification du bytecode pour le code douteux, la prise en charge de l’authentification et de la confidentialité, etc. Le programme Java s’exécute toujours dans l’environnement d’exécution Java avec une interaction quasi nulle avec le système d’exploitation, ce qui le rend plus sûr.
  • Exécutable   portable :   comme l’exprime   l’accroche Write Once Run  Anywhere,  un  programme Java, une fois écrit et compilé, peut être exécuté sans modification sur tout système sur lequel on peut installer une JVM.
  • Bibliothèque  très  riche :  la  bibliothèque  fournie  en standard  avec  Java  couvre  de  nombreux  domaines (gestion  de  collections,  accès  aux  bases  de  données, interface  utilisateur  graphique,  accès  aux  fichiers  et au réseau, utilisation d’objets distribués, XML…, sans compter toutes les extensions qui s’intègrent sans difficulté à Java).
  • Java est un langage nativement distribué : à l’ère d’Internet, les applications doivent fonctionner dans un environnement distribué. Cela est possible dans les applications Java puisque le programmeur peut utiliser les protocoles TCP/IP dans le code. Java propose le paquetage Remote Method Invocation (RMI) pour mettre en œuvre de telles interfaces dans une application multi-utilisateurs.

Les bases de la programmation Java

Maintenant que vous avez compris l’origine de java, son intérêt dans le monde professionnel, et les caractéristiques qui le rendent si attractif, il est temps d’entrer dans la programmation en Java proprement dite. Les parties précédentes étaient là pour planter le décor.

Structure d’un programme java

Examinons le programme le plus simple en Java.

public class Hello{
    public static void main(String[] args) {
          System.out.println("Hello world !" ) ;
    }
}

Ligne 1 :  tout code en Java doit se trouver dans une classe. Dans notre exemple, nous l’avons nommé Hello. Une classe doit toujours commencer par une majuscule.

Attention !!! le nom de la classe doit être le même que le nom du fichier java.

Ligne 2 : c’est le point d’entrée, la méthode principale de notre programme Java. La méthode main doit avoir cette signature exacte afin de pouvoir exécuter notre programme.

public static void main(String[] args) 

Vous n’avez pas besoin de comprendre les mots-clés avant et après le mot “main” pour le moment.  Nous en reparlerons dans la suite de l’article.

Ligne 3 : cette ligne est une instruction java permettant d’afficher une ligne de texte à l’écran.

Attention !!! une instruction en Java se termine toujours par un point virgule

Les commentaires en Java

Les commentaires sont de courtes notes que le développeur peut insérer dans son code. Cela permet au développeur d’expliquer son code. Le compilateur Java ignore complètement les commentaires, vous pouvez donc y dire n’importe quoi.

En java il existe principalement deux types de commentaires : les commentaires en une seule ligne écrits à l’aide de deux barres obliques(//) et les commentaires multi-lignes qui commencent par /* et se terminent par */.

/*
   ceci est un commentaire 
    multiligne
*/
public class Hello{
	public static void main(String[] args) {
		//Ceci est un commentaire sur une seule ligne
		System.out.println("Hello world !" );
	}
}

Les variables en Java

En programmation en générale, une variable est une sorte de boite permettant de stocker une ou plusieurs données. Cette variable a un nom qui permet d’ accéder et modifier son contenu ainsi qu’un type qui permet de définir le domaine de données qu’on peut y mettre.

variable en java

En Java on déclare une variable de la façon suivante :

int score = 20 ;

Pour modifier le contenu d’une variable, on utilise l’opérateur d’affectation (=) et on écrit de la façon suivante :

score = 50 ; 

Pour afficher cette variable à l’écran on écrit :

System.out.println(score) ;

En tant que programmeur, on est amené parfois à déclarer une variable constante afin qu’ il ne puisse pas être modifié intentionnellement ou accidentellement tout au long de l’exécution. Ainsi cette variable n’est initialisée qu’à sa déclaration et reste inchangé tout au long du programme.

En Java on déclare une constante  avec le mot clé final de la façon suivante:

final float PI = 3.14159 ;

Les types en Java

En Java, une donnée peut être de type primitif ou de type objet. Dans cette partie, nous nous intéresserons aux types primitifs et nous verrons les types objets plus tard dans l’article.

En java on distingue les types primitifs suivants : byte, short, int, long, float, double, boolean et char.

Le type byte

Le type byte peut stocker des nombres entiers de -128 à 127. Il peut être utilisé à la place de int ou d’autres types d’entiers pour économiser de la mémoire lorsque vous êtes certain que la valeur sera comprise entre -128 et 127. Par exemple :

byte nombre = 5 ;

Le type short

Le type short peut stocker des nombres entiers de -32768 à 32767. Par exemple :

short nombre = 2400 ; 

Le type int

Le type int peut stocker des nombres entiers compris entre -2147483648 et 2147483647. En général, le type  int est le type de données le plus utilisé lorsqu’on créé des variables avec une valeur numérique en java. Par exemple :

int nombre = 150000;

Le type long

Le type  long peut stocker des nombres entiers de -9223372036854775808 à 9223372036854775807. Il est utilisé lorsque int n’est pas assez grand pour stocker la valeur. Par exemple :

long nombre = 27800000000 ;

Le type float

Le type float peut stocker des nombres fractionnaires de 3,4e-038 à 3,4e+038. Par exemple :

float nombre = 4.5 ;

Le type double

Le type  double peut stocker des nombres fractionnaires compris entre 1,7e-308 et 1,7e+308. Par exemple :

double prix = 14.99;

Le type boolean

Un type boolean ne peut prendre que l’une des 2 valeurs suivantes : true ou false. Par exemple :

boolean estvide = false ;

Le type char

Le type char est utilisé pour stocker un seul caractère. Le caractère doit être entouré de cotes, comme ‘D’ ou ‘b’. Par exemple :

char lettre = 'a' ;

Une introduction au type String

Le type String permet de définir des chaînes de caractères en Java. Nous ferons une petite introduction de ce type assez spécial  et nous y reviendrons plus tard au cours de cet article.

Pour déclarer une variable de type String :

String databaseName = "MarketingDB";
// Longueur d'une chaine de caractère.
int longueurChaine = databaseName.length();  //cette ligne de code renvoie "11", qui est le nbre de caractère contenu dans la variable databaseName

La concaténation de chaînes de caractère se fait simplement avec l’opérateur +.

String chaine1 = "JAVA est un langage de  ";
String chaine2 = "programmation orientée objet";
String chaine = chaine1 + chaine2;
System.out.println(chaine); // affiche JAVA est un langage de programmation orientée objet.

Les opérateurs en Java

Dans un programme, on a des fois à effectuer des opérations sur les données telles que des additions, des soustractions, des multiplications, etc… On exprime ces opérations en java grâce aux groupes d’opérateurs suivants :

Les opérateurs arithmétiques

Opérateur

Nom

Description

Exemple

+

addition

effectue l’addition entre le contenu de 2 ou plusieurs variables

Soit a = 2; b= 0;

a + b = 2

soustraction

effectue la soustraction entre le contenu de 2 ou plusieurs variables

Soit a = 7; b= 2;

a – b = 5

*

multiplication

effectue la multiplication entre le contenu de 2 ou plusieurs variables

Soit a = 2; b= 5;

a *  b =10
/

division

effectue la division entre le contenu de 2 variables

Soit a = 16; b= 8;

a / b = 8

%

modulo

renvoie le reste de la division entre le contenu de 2 variables

Soit a = 5; b= 2;

a % b = 1

++

incrémentation

incrémente de 1 la valeur d’une variable

Soit a = 2; 

++a =3

décrémentation

décrémente de 1 la valeur d’une variable

Soit a = 5

–a = 4

Les opérateurs d’affectation

Ils permettent d’affecter une valeur à une variable.

Opérateur

Exemple

Autre écriture

=

a = 2

+=

a += 5

a = a + 5

-=

a -= 4

a = a – 4

*=

a *= 5

a = a * 5

/=

a /= 5

a = a / 5

%=

a %= 5

a = a % 5

&=

a &= 5

a = a & 5

|=

a |= 5

a = a | 5

^=

a ^= 5

a = a^5

>>=

a >>= 5

a = a >> 5

<<=

a <<= 5

a = a << 5

Les opérateurs de comparaison

Opérateur

Nom

Exemple

==

Egalité

Soit a = 2; b = 5;
a == b vaut false

!=

Non égalité

Soit a = 2; b = 5;
a != b vaut true

>

supériorité

Soit a = 2; b = 5;
a  > b vaut false

<
infériorité

Soit a = 2; b = 5;
a < b vaut true

>=

supérieur ou égal à 

Soit a = 2; b = 5;
a >= b vaut false

<=

inférieur ou égal à 

Soit a = 2; b = 5;
a >= b vaut true

Les opérateurs logiques

opérateur

Nom

Description

Exemple

&&

ET logique

retourne true si les deux conditions sont vraies

Soit a = 2; b = 5;
a < 4 && b > 4 vaut true

||

Ou logique

retourne true si une des conditions est vraies

Soit a = 2; b = 5;
a < 1 || b > 3 vaut true

!

Non logique

retourne true si la condition est fausse et false si la condition est vraie

Soit a = 5 ;
!( a == 5) vaut false

Avant de passer aux structures de contrôle en Java écrivons un programme qui résume tous les opérateurs et concepts vus précédemment.

public static void main(String[] args){
    
    // Déclaration de variables
    int a = 2;
    int b = 17;
    double c = 2.0;
    double d = 15.0;
    int e = 0, f = 0;
    
    int somme = a + b;
    int difference = a - b;
    int multi = a * b;
    double division =  d / c;
    
     //affectations
    e = ++a;
    f = --b;
    
    //Affichage
    System.out.println(somme); // 19
    System.out.println(difference); // - 15
    System.out.println(multi); // 34
    System.out.println(division); // 7.5
    System.out.println(a == b); // false
    System.out.println(b > a); // true
    System.out.println(e);// 3
    System.out.println(f); //16  
    
   }
	
}

Les structures de contrôle en Java

Java propose  un ensemble de structures de contrôle. Ces structures permettent de donner une certaine dynamique à vos programmes.

La structure conditionnelle if/else

La structure conditionnelle if permet d’exécuter un bloc d’instructions que si une condition est vraie.

if (condition) {
  // bloc d'instructions à éxecuter si la condition est vrai
}

L’expression else est utilisée pour spécifier le bloc d’instructions qui sera exécuté si la condition du if est fausse.

if (condition) {
    // bloc d'instructions à exécuter si la condition est vrai
}else {
   /* bloc d'instructions à exécuter si la condition est fausse*/
}

L’expression else if permet de définir une nouvelle condition si la première condition est fausse.

if (condition1) {
 // bloc d'instructions à exécuter si la condition est vrai
}else if(condition2){
  /* bloc d'instructions à exécuter si la condition est fausse*/
} else{
  /* bloc d'instruction à exécuter si la condition 1 est fausse de même que la condition 2 */
}

Il existe également un raccourci if else, connu sous le nom d’opérateur ternaire car il se compose de trois opérandes. Il peut être utilisé pour remplacer plusieurs lignes de code par une seule ligne. Il est souvent utilisé pour remplacer de simples instructions if else

variable = (condition) ? instructionVraie : instructionFausse

Par exemple :


public static void main(String[] args){
 int a = 2 ;
 boolean res = (a < 5) ? true : false ;
 System.out.println(res) //true
}

La structure conditionnelle switch()

Une expression switch permet d’effectuer une sélection parmi plusieurs valeurs.

switch(expression){
  case x:
	// bloc d'instructions
	break;
  case y:
	// bloc d'instructions
	break;
  default :
	// bloc d'instructions
}

 L’expression switch est évaluée une fois. La valeur de l’expression est comparée aux valeurs de chaque cas. S’il y a une correspondance, le bloc de d’instructions associé est exécuté. On peut ajouter un cas default qui servira de point d’exécution si aucune case ne correspond.

La boucle while()

L’expression while permet de définir un ensemble d’instructions à répéter tant que la condition est vraie.

while (condition) {
 /*
      bloc d'instructions à répeter tant que la condition est  
 */
}

La boucle do/while

La boucle do/while est une variante de la boucle while. Cette boucle va exécuter le bloc de code une fois, avant de vérifier si la condition est vraie, puis elle va répéter la boucle tant que la condition est vraie.


do {
 /*
    bloc d'instructions à exécuter  
 */
} while(condition) ;

La boucle For

Une expression for permet d’exécuter un bloc d’instructions un nombre de fois déterminé. Elle commence par initialiser l’itérateur puis exécute le bloc de code du développeur tant que la condition est vérifiée, et incrémente l’itérateur à chaque itération.

for(initialisation; condition; incrément){
  //bloc d'instructions
}

for(int i = 0; i <= 5; ++i){
   //bloc d'instructions
}

Les tableaux en java

Les tableaux sont utilisés pour stocker plusieurs valeurs dans une seule variable, au lieu de déclarer des variables distinctes pour chaque valeur. Pour déclarer un tableau en java, on définit le type de variable suivi de deux crochets

char[] letters ;

L’initialisation d’un tableau en Java se fait de la façon suivante :

char[] letters = { 'a', 'b', 'c', 'd'} ;

Pour accéder à un élément dans le tableau on se réfère à sa position dans le tableau. Par exemple, l’ accès au deuxième élément du tableau letters se fait de la manière suivante:

char[] letters = { 'a', 'b', 'c', 'd'} ;
char secondletter = letters[1] ;
System.out.println(secondletter) ; //affiche b

Attention !!! En Java, les indices des tableaux commencent par 0 : [0] est le premier élément. [1] est le deuxième élément, etc…

Pour changer la valeur d’une case d’un tableau on indique l’indice de l’élément à modifier et ensuite on lui affecte une valeur. Par exemple :

char[0] letters = 'g' ;

En Java pour connaitre la taille d’un tableau on utilise la méthode length de la manière suivante :

char[] letters = { 'a', 'b', 'c', 'd'};
char taille = letters.legnth;
System.out.println(taille); //affiche 4

On peut créer un tableau de plusieurs dimensions en Java. On crée un tableau de deux dimensions de la manière suivante:

char[][] letters = {{ 'a', 'b', 'c', 'd'}, {'e', 'f', 'g'}} ;

La programmation orientée objet en Java

La programmation orientée objet (POO) est un modèle de programmation informatique qui met en œuvre une conception basée sur les objets. Pour plus de détail sur ce paradigme, cliquez ici pour lire notre article complet : apprendre la programmation orientée objet par la pratique. Java est un langage orientée objet. Dans cette partie, nous allons vous montrer comment exploiter les fonctionnalités objet de Java.

Classes et objets en java

En Java, tout est associé à des classes et des objets, ainsi qu’à leurs attributs et méthodes. On peut avoir la classe Personne avec des  attributs : nom, prenom, age, etc.. et des méthodes comme manger.

Une classe est la description d’un ensemble d’objet qui possède une structure identique (attributs) et un même comportement (méthodes). Les objets sont construits à partir de la classe, par un processus appelé instanciation. De ce fait, tout objet est une instance de classe.

Exemple de classe en Java:

public class Personne{
   //Attributs
   private String nom = "toto";
   private String prenom;
   private int age;
	  
  //méthodes
  public String getNom(){ 
	return this.nom; 
  }

  public void setAge(int unage){ 
	this.age = age;
  }
}

Un objet est une instance d’une classe. Il contient tous les attributs et méthodes de la classe dont il est l’instance.

Les objets ne sont pas des éléments statiques et leur durée de vie ne correspond pas forcément à la durée d’exécution du programme.

La durée de vie d’un objet passe par trois étapes :

  •  la déclaration de l’objet et  son instanciation
  • l’utilisation de l’objet en appelant ses méthodes

la suppression de l’objet est automatique en Java grâce à la machine virtuelle. La restitution de la mémoire inutilisée est automatiquement prise en charge par le récupérateur de mémoire (garbage collector). Il n’existe pas d’instruction delete comme en C++.

Pour créer un objet, on spécifie le nom de la classe, suivi du nom de l’objet, et on utilise le mot clé new.

public static void main(String args[]){
    //création d'un objet
    Personne unePersonne = new Personne();
    String nom = unePersonne.getNom();
    System.out.println(nom); //affiche toto
}

Les méthodes en java

Une méthode est un bloc d’instructions permettant d’effectuer une tâche et qui correspond à une fonctionnalité offerte par sa classe. Une méthode peut retourner une valeur ou non.  Pour retourner une valeur en java, on utilise le mot-clé return. Une méthode en Java s’écrit selon la syntaxe suivante :

modificateurAcces typeRetour nomMethode(paramètres){
    //contenu de la méthode
}

Par exemple :

public int somme (int a, int b){
    return a + b ;
}

Lorsqu’une méthode ne renvoie aucune valeur elle a pour type de retour un void. Par exemple :

public void direBonjour(){
   system.out.println("Hello world ! ") ;
}

Exemple plus complet d’appel de méthode :

public class Hello {

  private String langue = "FR";
  
  public void sayHello(String uneLangue){
    this.langue = uneLangue;
    switch(this.langue){
        case "FR" : System.out.println("Bonjour"); break;
        case "EN" :  System.out.println("Hello"); break;
        default:    System.out.println("ERROR"); break;

    }
  }

public class Programme {

  public static void main(String[] args) {
    Hello hObject = new Hello();
    hObject.sayHello("EN");; //Appel de méthode
  }
}

En Java il existe des méthodes spéciales pour la création complète des classes. Ces méthodes sont : les constructeurs, les accesseurs et les mutateurs. Compte tenu de leur importance en programmation objet avec java, nous allons voir chacune d’entre elle en détail.

Le constructeur

Un constructeur en Java est une méthode  qui est utilisée pour initialiser les objets. Le constructeur est appelé lorsqu’une classe est instanciée (autrement dit, lorsqu’on crée un objet). Il est généralement utilisé pour définir les valeurs initiales (ou par défaut) des attributs de l’objet. Il existe deux types de constructeur en Java :

  • Le constructeur par défaut appelé par défaut lors de la création d’un objet (offert par défaut lors de la compilation s’il n’y a pas de constructeur déclaré)
  •  Le constructeur paramétrique appelé si la signature correspond à celle du constructeur

public class Hello {

  private String langue;
  public Hello(String langue){ // constructeur paramétrique
     
     this.langue = langue;
	
  }
  
  public void sayHello(){
      
    switch(this.langue){
      case "FR" : system.out.println("Bonjour"); break;
      case "EN" : system.out.println("Hello"); break;
      default :   system.out.println("ERROR"); break;
     }
	
  }
}

Attention !!! le constructeur a le même nom que sa classe

Les accesseurs et mutateurs

  • Les accesseurs (get) permettent de récupérer la  valeur des attributs sans y accéder directement de l’extérieur de la classe; ils sécurisent donc l’attribut en restreignant sa modification.
  • Les mutateurs (set) permettent de modifier la valeur des attributs tout en vérifiant si la valeur que  l’on veut donner à l’attribut respecte les normes définies par le développeur lors de la création de la classe.

Par exemple :

public class Hello {

  private String langue;
  public Hello(String langue){ 
     this.langue = langue;
  }
  
  public String getLangue(){ //accesseur
    return this.langue;
  }

  public void setLangue(){ //mutateur
     this.langue = langue;
  } 
	
}

La classe String

Comme nous le disions précédemment, le type String permet de définir les chaînes de caractères en Java. En réalité ce type est une classe créant des objets de type String. Étant une classe, elle possède des méthodes qui peuvent être accédées par toute chaîne de caractère.

On peut alors créer une chaîne de caractère de deux manières différentes :

String str = "bonjour" ;

ou bien

String str = new String("bonjour") ;

Quelques méthodes de la classe String à connaître :

char charAt(int i)

La méthode String charAt(int i) renvoie le caractère à la position i  d’ une chaîne de caractères. La valeur de i doit être comprise entre 0 et (longueur de la chaîne – 1).

 La méthode Java String charAt lève une IndexOutOfBoundsException, si la valeur de l’index passée dans la méthode charAt() est inférieure à 0 ou supérieure ou égale à la longueur de la chaîne (index<0|| index>=longueur()). Exemple:

String str = "bonjour" ;
char ch0 = str.charAt(0) ; // cho  vaut b

boolean equals(Object o)

 Cette méthode permet de comparer deux chaînes de caractères et renvoie true si les deux chaînes sont égales sinon elle renvoie false. Exemple :

String str = "bigData";
String str1 = "database";
boolean cmp = str.equals(str1); // cmp vaut false;

String toUpperCase()

Convertit les caractères d’une chaine de caractère en majuscules.

String str = "bigData";
System.out.println(str.toUpperCase()); // affiche BIGDATA

String toLowerCase()

Convertit les caractères d’une chaine de caractère en minuscules.

String str = "bigData";
System.out.println(str.toLowerCase()); // affiche bigdata

L’encapsulation en java

A titre de rappel, l’encapsulation est un mécanisme qui consiste à rassembler les données et les méthodes au sein d’une structure en cachant l’implémentation de l’objet, c’est-à-dire en empêchant l’accès aux données par un autre moyen que les services proposés. L’encapsulation permet donc de garantir l’intégrité des données contenues dans l’objet.

L’utilisateur d’une classe n’a pas forcément à savoir de quelle façon sont structurées les données dans l’objet, cela signifie qu’un utilisateur n’a pas à connaître l’implémentation. Ainsi, en interdisant l’utilisateur de modifier directement les attributs, et en l’obligeant à utiliser les fonctions définies pour les modifier, on est capable de s’assurer de l’intégrité des données. On pourra ainsi effectuer des contrôles sur les données entrées par l’utilisateur.

L’encapsulation permet de définir des niveaux de visibilité des éléments de la classe. Ces niveaux de visibilité définissent les droits d’accès aux données. Il existe trois niveaux de visibilité:

  • publique (+): les attributs publics sont accessibles à tous
  • protégée (#): les attributs protégés sont accessibles seulement dans la classe elle-même et aux classes dérivées.
  • privée (-): les attributs privés sont accessibles seulement par la classe elle-même.

Regardons le code suivant :


public class Voiture{

	//Déclaration des attributs
	private String couleur;
	private double poids;
	private int prix;
	  
	//Déclaration des méthodes
	void demarrer(){...}
	void accelerer(){...}
	public String getCouleur(){ // accesseur sur couleur
		return this.couleur; 
	}
	
	//mutateur sur couleur
	public void setCouleur(String uneCouleur){ 
		this.couleur = uneCouleur;
	}
}

public class Main{
   public static void main(String args[]){
      Voiture uneVoiture = new Voiture ();
      uneVoiture.poids = 1000;  // Erreur de compilation
   }
}

Le code ci-dessus met en œuvre un des avantages de l’encapsulation: le data hiding. L’attribut poids n’est accessible que par la classe Voiture. Du coup, l’accès à l’attribut entraînera une erreur de compilation.

Pour plus de détails sur l’encapsulation, consultez notre article de référence sur la programmation orientée objet.

L’héritage en Java

A titre de rappel, l’héritage désigne le principe selon lequel une classe peut hériter des caractéristiques (attributs et méthodes) d’autres classes.

En java l’héritage est défini par le mot clé extends.

public class Voiture extends Vehicule {...}
public class Avion extends Vehicule {...}

Une méthode dans une classe mère peut être redéfinie dans une classe fille : on parle de redéfinition. La nouvelle définition remplace celle héritée pour les objets de la classe dérivée. Le remplacement est effectif même quand l’objet de la classe fille est référencé par une variable typée par la super-classe (polymorphisme).

En Java voici comment cela s’implémente :


public class Point{
    protected int x, y;
    private void affiche(){
	system.out.println("x = "+ this.x + " y = " + this.y); 
    }
	
    Point (int x, int y){this.x = x; this.y = y;}
}

public class PointColore extends Point{
	private String couleur;
	PointColore(int x, int y, String couleur){
	   super(x, y); // appel du constructeur de la classe mère
	   this.couleur = couleur;
	 }

   //redéfinition de affiche()
    public void affiche(){
	   super.affiche(); //appel à affiche() de la classe mère
	   System.out.println(" couleur = " + this.couleur);
    } 
	
public class Main{

	public static void main(String args[]){
	    Point p = new Point (5, 2);
	    PointColore pc = new PointColore(7, 4, "verte");
	    p.affiche(); //x = 5  et y = 2;
	    pc.affiche(); // x = 7 et y = 4 couleur = verte
   }
}

Les avantages de l’héritage sont doubles :

  • Spécialisation : une nouvelle classe réutilise les attributs et les méthodes d’une classe en y ajoutant des opérations particulières à la nouvelle classe.
  • Réutilisation : évite de réécrire du code existant dans la classe mère.

Le polymorphisme en java

Un langage orienté objet est dit polymorphique s’il offre la possibilité de percevoir un objet en tant qu’instance de différentes classes selon la situation. Java est un langage  polymorphique.

public class A {

	public void f();
}

public class B extends A {

	public void k();
	
}

public class Main{
	public static void main (String [] args){
		A a1 = new B (...);//upcasting
} 

En examinant le code ci-dessus, vous pouvez remarquer qu’à  une  référence de type A  on affecte une référence vers un objet de la classe B : on parle de surclassement ou upcasting.

A la compilation a1 est considéré comme un objet de classe A. Ses services sont alors réduits à celles proposées par la classe A.

public class Main{
    public static void main (String [] args){
 	A a1 = new B(...);
	a1.f(); //ok
	a1.k(); // erreur de compilation
   } 
}

Examinons le code suivant :

public class Main{
   public static void main (String [] args){
     A a1 = new B(...);       				  			
     B b1 = (B) a1; // downcasting
} 

Dans le code ci-dessus  nous remarquons qu’à  une  référence de type B  on affecte une référence vers un objet de type A après une conversion : on parle de downcasting.

Les Classes abstraites en java

En programmation orientée objet, une classe abstraite est une classe dont l’implémentation n’est pas complète et qui n’est pas instanciable. Elle sert de base à d’autres classes dérivées (héritées). 

Une classe abstraite est définie de la façon suivante en Java :

public abstract class NomClasse {
  ...
}

L’interface en java

Une interface est un ensemble de signatures de méthodes, qui sont par essence abstraites et publiques ou des constantes.

Une classe peut implémenter une ou plusieurs interfaces à l’aide du mot clé implements, c’est à dire implémenter toutes les méthodes abstraites de l’interface. C’est l’héritage multiple en Java.

Les constantes d’une interface sont accessibles à toutes les classes implémentant l’interface.

public interface I1{
   static final int MIN = 25;
   void fonction1();

}

public interface I2{
   void fonction2();
}

public class A implements I1, I2{

	//Les méthodes fonction1 fonction2 des interfaces I1 et //I2 doivent être définies dans	la classe A
	 
	//dans toutes les méthodes de la classe A on a accès à // la constante MIN
	
}

Une interface ne permet pas d’instancier des objets, mais on peut définir des variables de type interface, qui peuvent référencer des objets d’une classe implémentant une interface.

public interface I {...}
public class A implements I {
	I i;
	i = new I(...);  //erreur de compilation
	i = new A ( ... );  //ok
}

Enum

Une enum est une “classe” spéciale qui représente un groupe de constantes.

Pour créer une enum, on utilise le mot-clé enum, et on sépare les constantes par une virgule. Notez qu’elles doivent être en lettres majuscules. Par exemple :

enum Log {
  WARNING,
  SUCCESS,
  ERROR
}

On accède au constante de l’enum de la façon suivante :

Log mylog = Log.SUCCESS

Ceci conclut la programmation orientée objet en java. Nous allons conclure cet article avec la programmation d’Apache Spark avec java.

Programmation java pour Apache Spark

Pour terminer ce tutoriel sur la programmation Java, nous allons aborder la programmation Java pour Apache Spark. La présentation que nous faisons de Spark ici est très sommaire. Si vous souhaitez aller plus loin avec Spark, cliquez ici pour télécharger 118 minutes de cours vidéo gratuits.

Apache Spark est une plateforme de calcul distribué open source lancée en 2010 par l’AMPLab de Berkeley. Elle est depuis devenue l’une des principales technologies utilisées pour le traitement des données à grande échelle. L’un de ses arguments de vente est l’API multilingue qui vous permet d’écrire du code Spark en Scala, Java, Python, R ou SQL (d’autres sont pris en charge de manière non officielle).

L’abstraction principale de Spark c’est le RDD (Resilient distributed dataset – jeu de données distribué et résilient). Cela signifie que lorsqu’on développe des applications en Spark, on travaille ultimement avec les RDD.

Formellement, un RDD est une collection partitionnée d’objets (instance de classe) accessible en lecture-seule. Etant donné qu’une RDD est une abstraction, elle n’a pas d’existence réelle, dès lors elle doit être explicitement créée ou instanciée à travers des opérations déterministes sur des fichiers de données existants ou sur d’autres instances de RDD.

Un exemple d’une Api RDD écrit en Java

Dans cet exemple, nous utilisons quelques transformations pour construire un jeu de données de paires (String, Int) appelé counts et le sauvegarder dans un fichier.

JavaRDD<String> textFile = sc.textFile("hdfs://...");
JavaPairRDD<String, Integer> counts = textFile
    .flatMap(s -> Arrays.asList(s.split(" ")).iterator())
    .mapToPair(word -> new Tuple2<>(word, 1))
    .reduceByKey((a, b) -> a + b);
counts.saveAsTextFile("hdfs://...");

Voilà ! Nous sommes arrivés au terme de ce guide complet sur le langage Java. Nous espérons que vous avez compris l’importance de Java dans le marché de la data et son intérêt pour l’ascension dans votre carrière. Pour aller plus loin en Java, vous pouvez consulter la documentation officielle. Aussi, nous vous recommandons de télécharger la vidéo de formation d’une heure en programmation Scala pour le Big Data ci-après pour mettre en pratique l’ensemble des concepts que vous avez acquis en lisant cet article.


Juvénal JVC

Juvénal est spécialisé depuis 2011 dans la valorisation à large échelle des données. Son but est d'aider les professionnels de la data à développer les compétences indispensables pour réussir dans le Big Data. Il travaille actuellement comme Lead Data Engineer auprès des grands comptes. Lorsqu'il n'est pas en voyage, Juvénal rédige des livres ou est en train de préparer la sortie d'un de  ses livres. Vous pouvez télécharger un extrait de son dernier livre en date ici : https://www.data-transitionnumerique.com/extrait-ecosystme-hadoop/

>