codestory

Die Anleitung zu Java Set

  1. Set
  2. Simple Examples
  3. stream()
  4. iterator()
  5. Wie prüft Set die Duplikat?
  6. of(..)
  7. spliterator()
  8. toArray​(..)

1. Set

Set ist eine Interface im Java Collection Framework und eine Unterinterface von Collection , sodass es alle Funktionen einer Collection hat.
Setist eine ungeordnete Collection (unordered Collection), erlaubt keine doppelten Elemente und kann höchstens 01 Element null enthalten. Wenn Sie dem Set absichtlich ein doppeltes Element hinzufügen, wird diese Aktion ignoriert und Set nicht geändert.
public interface Set<E> extends Collection<E>
SortedSet ist die Unterinterface von Set. Es kann die Elemente automatisch in ihrer natürlichen Reihenfolge oder basierend auf einem gestellten Comparatorsortieren.
Die Hierachie der Klassen implementiert die Interface Set.
Die Methode von Interface Set:
Set interface
boolean add​(E e)  
boolean addAll​(Collection<? extends E> c)  

void clear()  

boolean contains​(Object o)  
boolean containsAll​(Collection<?> c)  

boolean equals​(Object o)  
int hashCode()  
boolean isEmpty()  
int size()  

boolean remove​(Object o)  
boolean removeAll​(Collection<?> c)  
boolean retainAll​(Collection<?> c)  

Object[] toArray()  
<T> T[] toArray​(T[] a)

Iterator<E> iterator()  
default Spliterator<E> spliterator()  

static <E> Set<E> copyOf​(Collection<? extends E> coll)  

static <E> Set<E> of()  
static <E> Set<E> of​(E e1)  
static <E> Set<E> of​(E... elements)  
static <E> Set<E> of​(E e1, E e2)  
static <E> Set<E> of​(E e1, E e2, E e3)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)

2. Simple Examples

Set ist eine Interface. Um ein Objekt Set zu erstellen sollen Sie es über eine Klasse, die es implementiert, erstellen. Z.B HashSet, LinkedHashSet, TreeSet,..
Im folgenden Beispiel erstellen wir ein Objekt HashSet mit der Anfangskapazität von 10 Elementen. Die Kapazität erhöht sich um 80% wenn die Anzahl der Elemente die aktuelle Kapazität überschreitet.
SetEx1.java
package org.o7planning.set.ex;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SetEx1 {

    public static void main(String[] args) {
        Set<String> set = new HashSet<String>(10, (float) 0.8);

        set.add("One");
        set.add("Two");
        set.add("Three");
        
        Iterator<String> it1 = set.iterator();
        while (it1.hasNext()) {
            System.out.println(it1.next());
        }
        
        System.out.println(" ----- ");
        
        // When duplication occurs.
        // It will add new element and remove old element.
        set.add("Two");
        set.add("Four");

        Iterator<String> it2 = set.iterator();
        while (it2.hasNext()) {
            System.out.println(it2.next());
        }
    }
}
Achtung: Set ist ein ungeordnete Collection (unordered Collection) sodass Sie ein etwas anderes Ergebenis enthalten können, wenn Sie Elemente in dem Bildschirm Console drucken.
Output:
One
Two
Three
 -----
One
Four
Two
Three
Array --> Set?
Z.B: Wandeln Sie ein Array zu einem Objekt Set um.
ArrayToSetEx.java
package org.o7planning.set.ex;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

public class ArrayToSetEx {
    
    public static void main(String[] args) {
        Integer[] sourceArray = { 0, 3, 5, 3, 4, 5 };
        
        Set<Integer> targetSet = new HashSet<Integer>(Arrays.asList(sourceArray));
    
        for(Integer i : targetSet)  {
            System.out.println(i);
        }
    }  
}
Output:
0
3
4
5

3. stream()

Set ist eine Unterinterface von Collection, deshalb erbt sie das Methode stream(). Durch den Zugriff auf die Element einer Collection über Stream wird Ihr Code übersichtlich und verständlicher:
Set_stream.java
package org.o7planning.set.ex;

import java.util.HashSet;
import java.util.Set;

public class Set_stream {

    public static void main(String[] args) {  
        Set<String> set = new HashSet<String>();
        
        set.add("a1");
        set.add("b1");
        set.add("a2");  
        set.add("c1");  
        set.add("d1");  
        set.add("e1");  
        
        set.stream() //
              .map(String::toUpperCase) // to upsercase
              .filter(s -> !s.startsWith("A")) // Not starts with "A".
              .forEach(System.out::println);  
    }  
}
Output:
E1
D1
C1
B1

4. iterator()

iterator() ist das geerbte Methode aus Collection. Es gibt ein Objekt Iterator zurück um auf die Element von Collection zu iterieren (iterate).
Iterator<E> iterator()
Set_iterator.java
package org.o7planning.set.ex;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Set_iterator {

    public static void main(String[] args) {  
        Set<String> set = new HashSet<String>();
        
        set.add("a1");
        set.add("b1");
        set.add("a2");  
        
        Iterator<String> ite = set.iterator();
        
        while(ite.hasNext()) {
            System.out.println(ite.next());
        }
    }  
}
Output:
a1
a2
b1

5. Wie prüft Set die Duplikat?

Set ist eine Collection, die keine doppelten Elemente enthalten darf. Wenn Sie dem Set absichtlich ein doppeltes Element hinzufügen, wird diese Aktion ignoriert werden. So wird eine Frage gestellt, wie "Set" die Duplikat prüft?
SortedSet ist eine Unterinterface von Set. In diesem Teil erwähnen wir die reinen Typs Set (keine SortedSet). Die Klasse zur Vertretung eines reinen Set sind HashSet, LinkedHashSet, CopyOnWriteArraySet, EnumSet.
Die Art zur Duplikatsprüfung von SortedSet unterscheidet sich von der Art von reinen Set, und wird in diesem folgenden Artikel erwähnt:
HashSet / LinkedHashSet
HashSet (und LinkedHashSet) vergleichen hashcode zweier Elemente und vergleichen die beiden Elemente direkt über ihre Methode equals .
Sehen Sie 2 Beispiele HashSetDupTest1 & HashSetDupTest2 unten um das obengemeinte Kommentar besser zu verstehen.
HashSetDupTest1.java
package org.o7planning.set.test;

import java.util.HashSet;
import java.util.Set;

public class HashSetDupTest1 {

    public static class Student {
        private int studentId;
        private String studentName;
        
        public Student(int studentId, String studentName) {
            this.studentId = studentId;
            this.studentName = studentName;
        }
        public int getStudentId() {
            return studentId;
        }
        public String getStudentName() {
            return studentName;
        }
        @Override
        public boolean equals(Object other)  {
            if(other == null || !(other instanceof Student)) {
                return false;
            }
            Student o = (Student) other;
            return this.studentId == o.studentId;
        }
    }
    
    public static void main(String[] args) {
        Student s1 = new Student(1, "Tom");
        Student s2 = new Student(2, "Jerry");
        Student s3 = new Student(1, "Tom Cat"); // Same Id with s1.
        
        Set<Student> set = new HashSet<Student>();
        
        set.add(s1);
        set.add(s2);
        set.add(s3);

        for(Student s: set)  {
            System.out.printf("Student Id: %d / Name: %s (Hashcode: %s)\n", //
                    s.getStudentId(),s.getStudentName(),s.hashCode());
        }
    }
}
Output:
Student Id: 2 / Name: Jerry (Hashcode: 474675244)
Student Id: 1 / Name: Tom Cat (Hashcode: 932583850)
Student Id: 1 / Name: Tom (Hashcode: 1586600255)
Korigieren Sie das obengemeinte Beispiel mit dem Überschreiben (override) des Methode hashCode() in die Klasse Student:
HashSetDupTest2.java
package org.o7planning.set.test;

import java.util.HashSet;
import java.util.Set;

public class HashSetDupTest2 {

    public static class Student {
        private int studentId;
        private String studentName;
        
        public Student(int studentId, String studentName) {
            this.studentId = studentId;
            this.studentName = studentName;
        }
        public int getStudentId() {
            return studentId;
        }
        public String getStudentName() {
            return studentName;
        }
        @Override
        public boolean equals(Object other)  {
            if(other == null || !(other instanceof Student)) {
                return false;
            }
            Student o = (Student) other;
            return this.studentId == o.studentId;
        }
        @Override
        public int hashCode() { // -----> Override hashCode() method.
            return this.studentName.charAt(0);
        }
    }
    
    public static void main(String[] args) {
        Student s1 = new Student(1, "Tom");   // Hashcode: 84 ('T')
        Student s2 = new Student(1, "Tom Cat"); // Hashcode: 84 ('T')
        
        Student s3 = new Student(2, "Jerry"); // Hashcode: 74 ('J')
        
        Student s4 = new Student(4, "Daffy"); // Hashcode: 68 ('D')
        Student s5 = new Student(5, "Donald"); // Hashcode: 68 ('D')
        
        
        Set<Student> set = new HashSet<Student>();
        
        set.add(s1);
        set.add(s2); // a Duplication (Ignored!)
        set.add(s3);
        set.add(s4);  
        set.add(s5);  

        for(Student s: set)  {
            System.out.printf("Student Id: %d / Name: %s (Hashcode: %s)\n", //
                    s.getStudentId(),s.getStudentName(),s.hashCode());
        }
    }
}
Output:
Student Id: 1 / Name: Tom (Hashcode: 84)
Student Id: 4 / Name: Daffy (Hashcode: 68)
Student Id: 5 / Name: Donald (Hashcode: 68)
Student Id: 2 / Name: Jerry (Hashcode: 74)
CopyOnWriteArraySet
CopyOnWriteArraySet vergleichen 1 Elemente direkt über ihr Methode equals.
Sehen Sie 2 Beispiele CopyOnWriteArraySetDupTest1 & CopyOnWriteArraySetDupTest2 unten um das obengemeinte Kommentar besser zu verstehen.
CopyOnWriteArraySetDupTest1.java
package org.o7planning.set.test;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

public class CopyOnWriteArraySetDupTest1 {

    public static class Employee {
        private int empId;
        private String empName;
        
        public Employee(int empId, String empName) {
            this.empId = empId;
            this.empName = empName;
        }
        public int getEmpId() {
            return empId;
        }
        public String getEmpName() {
            return empName;
        }
        // Employee class uses equals(Object) method inherited from Object class.
    }
    
    public static void main(String[] args) {
        Employee s1 = new Employee(1, "Tom");    
        Employee s2 = new Employee(2, "Jerry");  
        Employee s3 = new Employee(1, "Tom Cat");  
        
        Set<Employee> set = new CopyOnWriteArraySet<Employee>();
        
        set.add(s1);
        set.add(s2);
        set.add(s3);  

        for(Employee s: set)  {
            System.out.printf("Emp Id: %d / Name: %s\n", //
                    s.getEmpId(),s.getEmpName());
        }
    }
}
Output:
Emp Id: 1 / Name: Tom
Emp Id: 2 / Name: Jerry
Emp Id: 1 / Name: Tom Cat
Korrigieren Sie das Beispiel über dem Überschreiben (override) des Methode equals(Object) in die Klasse Employee:
CopyOnWriteArraySetDupTest2.java
package org.o7planning.set.test;

import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

public class CopyOnWriteArraySetDupTest2 {

    public static class Employee {
        private int empId;
        private String empName;
        
        public Employee(int studentId, String studentName) {
            this.empId = studentId;
            this.empName = studentName;
        }
        public int getEmpId() {
            return empId;
        }
        public String getEmpName() {
            return empName;
        }
        @Override
        public boolean equals(Object other)  { // -----> Override equals() method.
            if(other == null || !(other instanceof Employee)) {
                return false;
            }
            Employee o = (Employee) other;
            return this.empId == o.empId;
        }
    }
    
    public static void main(String[] args) {
        Employee s1 = new Employee(1, "Tom");   
        Employee s2 = new Employee(2, "Jerry");  
        Employee s3 = new Employee(1, "Tom Cat");
        
        Set<Employee> set = new CopyOnWriteArraySet<Employee>();
        
        set.add(s1);
        set.add(s2);
        set.add(s3); // a Duplication.

        for(Employee s: set)  {
            System.out.printf("Emp Id: %d / Name: %s\n", //
                    s.getEmpId(),s.getEmpName());
        }
    }
}
Output:
Emp Id: 1 / Name: Tom
Emp Id: 2 / Name: Jerry

6. of(..)

Das static Methode Set.of(..) gibt das Objekt Set mit einer festen Größe zurück. Eine Ausnahme wird geworfen wenn die Eingangparameter doppelt sind. Das Objekt Set unterstützt die benutzerdefininierten Methode add, remove, set und clear nicht.
static <E> Set<E> of()  
static <E> Set<E> of​(E e1)  
static <E> Set<E> of​(E... elements)  
static <E> Set<E> of​(E e1, E e2)  
static <E> Set<E> of​(E e1, E e2, E e3)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)  
static <E> Set<E> of​(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
Set_of.java
package org.o7planning.set.ex;

import java.util.Iterator;
import java.util.Set;

public class Set_of {

    public static void main(String[] args) {
        Set<Integer> set = Set.of(1, 2, 5, 3, 7, 9, 0);

        Iterator<Integer> it2 = set.iterator();
        while (it2.hasNext()) {
            System.out.println(it2.next());
        }
    }
}
Achtung: Set ist eine ungeordnete Collection (unordered Collection) deshalb bekommen Sie ein etwas anderes Ergebenis wenn Sie die Elemente auf dem Bildschirm Console ausdrucken.
Output:
2
3
5
7
9
0
1

7. spliterator()

Erstellen Sie ein Objekt Spliterator zum Durchlaufen und Partitionieren (traversing and partitioning) für die Elemente von Set.
default Spliterator<E> spliterator()
Spliterator wird zum Durchlaufen und Partitionieren (traversing and partitioning) breit für die unterschiedlichen Datenquelle wie Collection (List, Set, Queue), BaseStream, array.
  • Die Anleitung zu Java Spliterator

8. toArray​(..)

Das Array toArray(..) gibt ein Array mit allen Elementen von Set zurück.
Object[] toArray()  

<T> T[] toArray​(T[] a)

// Java 11, The default method, inherited from Collection.
default <T> T[] toArray​(IntFunction<T[]> generator)
Set_toArray.java
package org.o7planning.set.ex;

import java.util.HashSet;
import java.util.Set;

public class Set_toArray {

    public static void main(String[] args) {  
        Set<String> set = new HashSet<String>();
        
        set.add("a1");
        set.add("b1");
        set.add("a2");  
        
        String[] array = new String[set.size()];
        
        set.toArray(array);
        
        for(String s: array) {
            System.out.println(s);
        }
    }  
}
Output:
a1
a2
b1