devstory

Le Tutoriel de Java SortedSet

  1. SortedSet
  2. Examples
  3. L'élément null
  4. subSet(E fromElement, E toElement)
  5. headSet(E toElement)
  6. tailSet(E fromElement)
  7. spliterator()
  8. first()
  9. last()

1. SortedSet

SortedSet est une sous-interface de Set, il dispose alors de toutes les caractéristiques de Set. La différence est que les éléments SortedSet sont triés par ordre croissant selon leur ordre naturel ou par un Comparator fourni.
Les éléments de SortedSet sont classés par ordre croissant.
public interface SortedSet<E> extends Set<E>
Ci-dessous une comparaison entre Set et SortedSet:
Set<E>
SortedSet<E> / NavigableSet<E>
Les éléments dupliqués ne sont pas autorisés. Si vous ajoutez intentionnellement un élément dupliqué à Set, cette action sera ignorée.
Les éléments dupliqués ne sont pas autorisés. Si vous ajoutez intentionnellement un élément dupliqué dans SortedSet, cette action sera ignorée.
Autoriser au maximum un élément null.
Autoriser au maximum un élément null.
L'ordre des éléments n'est pas garanti.
L'ordre des éléments est garanti.
Tous les éléments de SortedSet doivent être de type Comparable, ou vous devez fournir un Comparator à SortedSet pour qu'il puisse comparer les éléments. Sinon, ClassCastException sera levée.
Par conséquent, lorsque vous ajoutez un élément à SortedSet, vous ne pouvez pas spécifier sa position. La position de l'élément inséré est déterminée par son ordre naturel ou par le Comparator fourni.
SortedSet Methods
Comparator<? super E> comparator()

SortedSet<E> subSet(E fromElement, E toElement)

SortedSet<E> headSet(E toElement)

SortedSet<E> tailSet(E fromElement)

E first()  

E last()  

default Spliterator<E> spliterator()

2. Examples

La classe Employee suivante simule un employé avec des informations sur fullName et salary. La classe Employee implémente l'interface Comparable<Employee>, ce qui signifie que les objets Employee sont comparables.
Deux objets Employee peuvent être comparés selon la règle suivante: En comparant par salary, s'ils ont le même salary, fullName sera utilisé pour comparer.
Employee.java
package org.o7planning.bean;

public class Employee implements Comparable<Employee> {

    private String fullName;
    private float salary;

    public Employee(String name, float salary) {
        this.fullName = name;
        this.salary = salary;
    }

    public String getFullName() {
        return fullName;
    }

    public float getSalary() {
        return salary;
    }
    
    // Implements method of Comparable<Employee>
    @Override
    public int compareTo(Employee o) {
        float delta = this.salary - o.salary;
        if (delta > 0) {
            return 1;
        } else if (delta < 0) {
            return -1;
        }
        return this.fullName.compareTo(o.fullName);
    }
}
Comparable<Employee>
Par exemple: Utiliser TreeSet pour stocker les objets Employee, ils seront classés par ordre croissant.
SortedSetEx1.java
package org.o7planning.sortedset.ex;

import java.util.SortedSet;
import java.util.TreeSet;

import org.o7planning.bean.Employee;

public class SortedSetEx1 {

    public static void main(String[] args) {
        Employee e1 = new Employee("Tom A", 5000);
        Employee e2 = new Employee("Jerry A", 1000);
        Employee e3 = new Employee("Tom B", 1000);
        Employee e4 = new Employee("Jerry B", 5000);
        Employee e5 = new Employee("Donald A", 1000);
        
        SortedSet<Employee> employees = new TreeSet<Employee>();
        
        employees.add(e1);
        employees.add(e2);
        employees.add(e3);
        employees.add(e4);
        employees.add(e5);

        for(Employee e: employees)  {
            System.out.println(e.getSalary() + " / " + e.getFullName());
        }
    }
}
Output:
1000.0 / Donald A
1000.0 / Jerry A
1000.0 / Tom B
5000.0 / Jerry B
5000.0 / Tom A
Comparable<String>
Les objets String sont également comparables selon leur ordre alphabletique.
SortedSetEx2.java
package org.o7planning.sortedset.ex;

import java.util.SortedSet;
import java.util.TreeSet;

public class SortedSetEx2 {

    public static void main(String[] args) {   
        SortedSet<String> flowers = new TreeSet<String>();
        
        flowers.add("Rose");
        flowers.add("Lily");
        flowers.add("Tulip");
        flowers.add("Orchid");
        flowers.add("Carnation");
        flowers.add("Hyacinth");
        flowers.add("Peruvian");

        for(String flower: flowers)  {
            System.out.println(flower);
        }
    }  
}
Output:
Carnation
Hyacinth
Lily
Orchid
Peruvian
Rose
Tulip
Comparator<E>
La classe Staff suivante n'implémente pas l'interface Comparable, par conséquent, les objets Staff ne sont pas comparables entre eux. Si vous souhaitez stocker les objets Staff dans un SortedSet, vous devez fournir un Comparator.
Staff.java
package org.o7planning.bean;

public class Staff {
    private String fullName;
    private float salary;
    public Staff(String fullName, float salary) {
        super();
        this.fullName = fullName;
        this.salary = salary;
    }
    public String getFullName() {
        return fullName;
    }
    public float getSalary() {
        return salary;
    }
}
La classe MyStaffComparator permet de comparer deux objets Staff en se basant sur leur salary et fullName.
MyStaffComparator.java
package org.o7planning.sortedset.ex;

import java.util.Comparator;

import org.o7planning.bean.Staff;

public class MyStaffComparator implements Comparator<Staff> {

    @Override
    public int compare(Staff o1, Staff o2) {
        float delta = o1.getSalary() - o2.getSalary();
        if (delta > 0) {
            return 1;
        } else if (delta < 0) {
            return -1;
        }
        return o1.getFullName().compareTo(o2.getFullName());
    }
}
SortedSetEx3.java
package org.o7planning.sortedset.ex;

import java.util.SortedSet;
import java.util.TreeSet;

import org.o7planning.bean.Staff;

public class SortedSetEx3 {

    public static void main(String[] args) {
        Staff e1 = new Staff("Tom A", 5000);
        Staff e2 = new Staff("Tom A", 2000);
        Staff e3 = new Staff("Jerry A", 1000);
        Staff e4 = new Staff("Tom B", 1000);
        Staff e5 = new Staff("Jerry B", 5000);
        Staff e6 = new Staff("Donald A", 1000);

        // Custom Comparator.
        MyStaffComparator comparator = new MyStaffComparator();
        // A SortedSet with specified Comparator.
        SortedSet<Staff> employees = new TreeSet<Staff>(comparator);

        employees.add(e1);
        employees.add(e2);
        employees.add(e3);
        employees.add(e4);
        employees.add(e5);
        employees.add(e6);

        for (Staff e : employees) {
            System.out.println(e.getSalary() + "/" + e.getFullName());
        }
    }
}
Output:
1000.0/Donald A
1000.0/Jerry A
1000.0/Tom B
2000.0/Tom A
5000.0/Jerry B
5000.0/Tom A
Comparator est une functional interface, par conséquent, il est possible de créer l'objet Comparator selon la syntaxe Lambda. OK, on reformule l'exemple ci-dessus de manière plus concise:
SortedSetEx3A.java
package org.o7planning.sortedset.ex;

import java.util.Comparator;
import java.util.SortedSet;
import java.util.TreeSet;

import org.o7planning.bean.Staff;

public class SortedSetEx3A {

    public static void main(String[] args) {
        Staff e1 = new Staff("Tom A", 5000);
        Staff e2 = new Staff("Tom A", 2000);
        Staff e3 = new Staff("Jerry A", 1000);
        Staff e4 = new Staff("Tom B", 1000);
        Staff e5 = new Staff("Jerry B", 5000);
        Staff e6 = new Staff("Donald A", 1000);

        // Custom Comparator.
        Comparator<Staff> comparator = (s1, s2) -> {
            float delta = s1.getSalary() - s2.getSalary();
            if (delta > 0) {
                return 1;
            } else if (delta < 0) {
                return -1;
            }
            return s1.getFullName().compareTo(s2.getFullName());
        };
        // A SortedSet with specified Comparator.
        SortedSet<Staff> employees = new TreeSet<Staff>(comparator);

        employees.add(e1);
        employees.add(e2);
        employees.add(e3);
        employees.add(e4);
        employees.add(e5);
        employees.add(e6);

        for (Staff e : employees) {
            System.out.println(e.getSalary() + "/" + e.getFullName());
        }
    }
}

3. L'élément null

La spécification de l'interface SortedSet et NavigableSet ne mentionne pas du tout les éléments null, ce qui signifie qu'ils peuvent autoriser au maximum un élément null (héritant de la spécification de l'interface Set). Par conséquent, si SortedSet et NavigabletSet autorisent ou non l'élément null, cela dépend de la classe qui implémente ces interfaces.
Dans Java Collection Framework, la classe TreeSet implémente l'interface NavigableSet, autorisant l'élément null si vous lui fournissez un Comparator pour gérer la comparaison d'élément null avec ses autres éléments. Entretemps, ConcurrentSkipListSet implémente également l'interface NavigableSet mais n'autorise aucun élément null dans aucune situation.
Observer l'exemple suivant, TreeSet et l'élément null.
Circle.java
package org.o7planning.bean;

public class Circle  {
    private double radius;

    public Circle(double radius) {
        super();
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }
}
La classe CircleComparator implémente l'interface Comparator<Circle>, qui peut comparer deux objets Circle, incluant l'objet null:
CircleComparator.java
package org.o7planning.sortedset.ex;

import java.util.Comparator;

import org.o7planning.bean.Circle;

public class CircleComparator implements Comparator<Circle> {

    @Override
    public int compare(Circle o1, Circle o2) {
        if (o1 == null && o2 == null) {
            return 0;
        }
        if (o1 == null) {
            return -1; // o1 < o2
        } else if (o2 == null) {
            return 1; // o1 > o2
        }
        double delta = o1.getRadius() - o2.getRadius();
        if (delta < 0) {
            return -1; // o1 < o2
        } else if (delta > 0) {
            return 1; // o1 > o2
        }
        return 0;
    }
}
Par exemple: Un objet TreeSet contient l'élément null:
SortedSet_null_element_ex1.java
package org.o7planning.sortedset.ex;

import java.util.TreeSet;

import org.o7planning.bean.Circle;

public class SortedSet_null_element_ex1 {

    public static void main(String[] args) {
        Circle c1 = new Circle(3);
        Circle c2 = new Circle(5);
        Circle c3 = new Circle(9);
        Circle c4 = new Circle(7);

        // Create a SortedSet with provided Comparator.
        TreeSet<Circle> set = new TreeSet<Circle>(new CircleComparator());

        set.add(null); // Add null Element
        set.add(c1);
        set.add(c2);
        set.add(c3);
        set.add(c4);

        for (Circle c : set) {
            System.out.println("Circle: " + (c == null?null : c.getRadius()));
        }
    }
}
Output:
Circle: null
Circle: 3.0
Circle: 5.0
Circle: 7.0
Circle: 9.0

4. subSet(E fromElement, E toElement)

public SortedSet<E> subSet(E fromElement, E toElement)
Renvoyer une vue partielle d'un élément de ce SortedSet dont les éléments se situent de fromElement à toElement (fromElement =< element < toElement). (Si fromElement et toElement sont égaux, SortedSet renvoyé est vide).
SortedSet renvoyé est relatif à l'actuel SortedSet, les changements sur ce SortedSet affectent à l'autre SortedSet et inversement.
SortedSet_subSet_ex1.java
package org.o7planning.sortedset.ex;

import java.util.SortedSet;
import java.util.TreeSet;

public class SortedSet_subSet_ex1 {

    public static void main(String[] args) {  
        SortedSet<String> mySet = new TreeSet<String>();
        
        mySet.add("A");
        mySet.add("B");
        mySet.add("C");
        mySet.add("D");
        mySet.add("E");

        // A Sub Set
        SortedSet<String> subSet = mySet.subSet("B", "C1");
        
        System.out.println(" -- subSet --");
        for(String s: subSet)  {
            System.out.println(s);
        }
        
        subSet.add("B1");
        subSet.add("B2");
        
        System.out.println(" -- subSet (after adding elements to subSet) --");
        for(String s: subSet)  {
            System.out.println(s);
        }
        
        System.out.println(" -- mySet (after adding elements to subSet) --");
        for(String s: mySet)  {
            System.out.println(s);
        }
    }
}
Output:
-- subSet --
B
C
 -- subSet (after adding elements to subSet) --
B
B1
B2
C
 -- mySet (after adding elements to subSet) --
A
B
B1
B2
C
D
E

5. headSet(E toElement)

public SortedSet<E> headSet(E toElement)
Renvoyer une vue partielle de ce SortedSet dont les éléments sont strictement inférieurs toElement. (element < toElement)
SortedSet renvoyé est relatif à l'actuel SortedSet, les changements sur ce SortedSet affectent à l'autre SortedSet et inversement.
Par exemple:
SortedSet_headSet_ex1.java
package org.o7planning.sortedset.ex;

import java.util.SortedSet;
import java.util.TreeSet;

public class SortedSet_headSet_ex1 {

    public static void main(String[] args) {
        SortedSet<String> mySet = new TreeSet<String>();

        mySet.add("A");
        mySet.add("B");
        mySet.add("C");
        mySet.add("D");
        mySet.add("D1");
        mySet.add("E");

        // A Head Set (elements < "D1")
        SortedSet<String> headSet = mySet.headSet("D1");

        System.out.println(" -- headSet --");
        for (String s : headSet) {
            System.out.println(s);
        }
    }
}
Output:
-- headSet --
A
B
C
D

6. tailSet(E fromElement)

public SortedSet<E> tailSet(E fromElement)
Renvoyer une vue partielle d'un élément de ce SortedSet dont les éléments sont supérieurs ou égaux à fromElement. (element >= fromElement).
SortedSet renvoyé est relatif à l'actuel SortedSet, les changements sur ce SortedSet affectent à l'autre SortedSet et inversement.

7. spliterator()

public default Spliterator<E> spliterator()
  • Java Spliterator

8. first()

public E first()
Renvoyer le premier élément (le plus petit) de SortedSet.

9. last()

public E last()
Renvoyer le dernier élément (le plus grand) de SortedSet.