Récapitulatif des valeurs renvoyées par la méthode des caractéristiques Spliterator #java

Récapitulatif des valeurs renvoyées par la méthode des caractéristiques Spliterator #java

L'interface d'itérateur Spliterator, ajoutée dans Java 8, peut conserver les caractéristiques de sa source de données. J'ai senti qu'il y avait des cas où il n'était pas évident de savoir quelles caractéristiques devraient être possédées, j'ai donc résumé les valeurs des «caractéristiques» renvoyées par «Spliterator» créées via la bibliothèque standard.

Spliterator est ce que

java.util.Spliterator est une nouvelle interface d'itérateur ajoutée dans Java 8. https://docs.oracle.com/javase/jp/8/docs/api/java/util/Spliterator.html

En parlant d'itérateurs Java, java.util.Iterator existe depuis l'Antiquité. Spliterator est à peu près le même que cet ʻIterator`, mais fournit une API plus optimisée.

tryAdvance

Dans le cas de java.util.Iterator, la méthode hasNext et la méthode next sont combinées pour itérer l'élément. Le protocole consiste à utiliser «hasNext» pour vérifier si l'élément «suivant» existe, et si c'est le cas, utilisez «suivant» pour obtenir cet élément.

Iterator<String> iterator = ……;
while (iterator.hasNext()) {
  System.out.println(iterator.next());
}

D'autre part, Spliterator fournit une méthode unique appelée tryAdvance pour obtenir l'élément" suivant ". tryAdvance prend un élément de Spliterator et fait quelque chose Consumer Prend comme argument. Si l'élément «suivant» existe, il sera digéré par «Consumer» et retournera «true». Si l'élément «next» n'existe pas, «Consumer» ne sera pas exécuté et «false» sera renvoyé.

Spliterator<String> spliterator = ……;
do { } while (spliterator.tryAdvance(System.out::println));

trySplit

Le nom de l'interface cache également sa fonctionnalité, mais Spliterator fournit une méthode trySplit pour diviser les itérateurs. Il s'agit d'une API qui divise les éléments du récepteur «Spliterator» dans le «Spliterator» de retour.

Habituellement, un seul «Itérateur» ou «Spliterator» n'est pas thread-safe. Cependant, chaque Spliterator divisé par trySplit peut être traité par un thread séparé, ce qui permet de traverser des éléments en parallèle. De plus, «Spliterator» est une interface qui est fortement consciente de la gouvernance parallèle / fractionnée, par exemple être capable d'acquérir le nombre d'éléments et de spécifier les caractéristiques décrites plus loin. StreamSupport utilise ce «trySplit» et ses caractéristiques pour optimiser le flux. C'est vrai.

Par exemple, si vous appelez trySplit de Spliterator créé à partir d'un tableau comme suit, chaque Spliterator sera divisé de sorte qu'il soit responsable d'exactement la moitié des éléments.

final int[] xs = {1, 2, 3, 4, 5, 6, 7, 8};
final Spliterator<Integer> a = Spliterators.spliterator(xs, 0);
final Spliterator<Integer> b = a.trySplit();
a.forEachRemaining(System.out::println); // 5, 6, 7, 8
b.forEachRemaining(System.out::println); // 1, 2, 3, 4

Ce que je voulais savoir

Quelles caractéristiques devraient être

«Spliterator» peut stocker des indices en fonction de ses propres caractéristiques. Actuellement, les fonctionnalités que Spliterator peut avoir sont" CONCURRENT "et" DISTINCT. "" [IMMUTABLE](https://docs.oracle.com/javase/ jp / 8 / docs / api / java / util / Spliterator.html # IMMUTABLE) "" [NON NULL](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Spliterator. html # NONNULL) "" COMMANDÉ "" [SIZED](https: // docs.oracle.com/javase/jp/8/docs/api/java/util/Spliterator.html#SIZED) "" [TRIÉ](https://docs.oracle.com/javase/jp/8/docs/ api / java / util / Spliterator.html # SORTED) "" SUBSIZED " Il y en a huit.

La signification est la même que le nom de la constante, par exemple, Spliterator fabriqué à partir de Set est garanti sans éléments en double, donc l'attribut DISTINCT est ajouté. Spliterator fait à partir d'un tableau a le nombre d'éléments. Puisque nous le savons, nous l'utilisons comme l'ajout de l'attribut SIZED.

Cependant, j'étais un peu inquiet au sujet des spécifications, car il n'était pas clair si l'attribut DISTINCT ou l'attribut SORTED devait être ajouté alors qu'il était clair qu'il n'y avait qu'un seul élément. J'ai donc décidé de créer Spliterator de différentes manières et de voir la relation entre la structure des données et les caractéristiques.

résultat

Comme il y a beaucoup de cas d'enquête, j'ai divisé les résultats en plusieurs modèles. La source de «Spliterator», la classe concrète générée de «Spliterator» et les caractéristiques de «Spliterator» sont décrites respectivement.

Créé à partir de java.util.Iterator

Je les ai créés avec Spliterators.spliterator et Spliterators.spliteratorUnknownSize, respectivement. C'était le résultat de cela.

La source Classe de béton Spliterator Caractéristiques du séparateur
Avec spécification de taille java.util.Spliterators$IteratorSpliterator SIZED, SUBSIZED
Aucune taille spécifiée java.util.Spliterators$IteratorSpliterator Aucun

Créé à partir d'un tableau ou d'une collection régulière

Il semble que les caractéristiques de la structure des données soient exprimées. Cependant, je craignais que le Spliterator issu d'un tableau n'ait la propriété ʻORDERED`.

La source Classe de béton Spliterator Caractéristiques du séparateur
Tableau java.util.Spliterators$ArraySpliterator SIZED, SUBSIZED
ArrayList java.util.ArrayList$ArrayListSpliterator ORDERED, SIZED, SUBSIZED
LinkedList java.util.LinkedList$LLSpliterator ORDERED, SIZED, SUBSIZED
HashSet java.util.HashMap$KeySpliterator DISTINCT, SIZED
LinkedHashSet java.util.Spliterators$IteratorSpliterator DISTINCT, ORDERED, SIZED, SUBSIZED
TreeSet java.util.TreeMap$KeySpliterator DISTINCT, ORDERED, SIZED, SORTED
PriorityQueue java.util.PriorityQueue$PriorityQueueSpliterator NONNULL, SIZED, SUBSIZED

Créé à partir d'une collection parallèle

Presque tous les modèles ont la caractéristique «IMMUTABLE» ou «CONCURRENT». Je pense que la raison pour laquelle ils ne sont pas dans la PriorityBlockingQueue est due à la structure de données du tas.

La source Classe de béton Spliterator Caractéristiques du Spliterator
CopyOnWriteArrayList java.util.Spliterators$ArraySpliterator IMMUTABLE, ORDERED, SIZED, SUBSIZED
CopyOnWriteArraySet java.util.Spliterators$ArraySpliterator DISTINCT, IMMUTABLE, SIZED, SUBSIZED
ConcurrentSkipListSet java.util.concurrent.ConcurrentSkipListMap$KeySpliterator CONCURRENT, DISTINCT, NONNULL, ORDERED, SORTED
ConcurrentLinkedQueue java.util.concurrent.ConcurrentLinkedQueue$CLQSpliterator CONCURRENT, NONNULL, ORDERED
LinkedBlockingQueue java.util.concurrent.LinkedBlockingQueue$LBQSpliterator CONCURRENT, NONNULL, ORDERED
LinkedTransferQueue java.util.concurrent.LinkedTransferQueue$LTQSpliterator CONCURRENT, NONNULL, ORDERED
PriorityBlockingQueue java.util.concurrent.PriorityBlockingQueue$PBQSpliterator NONNULL, SIZED, SUBSIZED

Modèles avec des restrictions spéciales

J'ai essayé des listes de singleton immuables créées à l'aide de la classe Collections, des listes de ciel immuables, etc. Pour être honnête, je pense que les caractéristiques de la collection Immutable Sky ne sont pas suffisantes.

La source Classe de béton Spliterator Caractéristiques du Spliterator
Collections.singletonList java.util.Collections$2 DISTINCT, IMMUTABLE, NONNULL, ORDERED, SIZED, SUBSIZED
Collections.singleton java.util.Collections$2 DISTINCT, IMMUTABLE, NONNULL, ORDERED, SIZED, SUBSIZED
Collections.emptyList java.util.Spliterators$EmptySpliterator$OfRef SIZED, SUBSIZED
Collections.emptySet java.util.Spliterators$EmptySpliterator$OfRef SIZED, SUBSIZED
Collections.emptySortedSet java.util.TreeMap$KeySpliterator DISTINCT, ORDERED, SIZED, SORTED
Spliterators.emptySpliterator java.util.Spliterators$EmptySpliterator$OfRef SIZED, SUBSIZED

Résumé

J'ai créé Spliterator de différentes manières et j'ai essayé d'obtenir les caractéristiques de chacun. Bien que j'aie saisi la tendance générale, il semble que la bibliothèque standard elle-même ne soit pas nécessairement une implémentation cohérente.

Historique de l'enquête

Ceci est le journal d'enquête. Comme il est long, nous vous recommandons de vous référer au résumé des résultats.

Java est "Java HotSpot (TM) 64-Bit Server VM, Java 1.8.0_60".

supposition

Je l'ai essayé avec Scala REPL. Effectuez à l'avance l'importation suivante et la définition de méthode.

import java.util._
import java.util.concurrent._
def printCharacteristics[T](spliterator:Spliterator[T]): Unit = {
  println(Seq(
    if (spliterator.hasCharacteristics(Spliterator.CONCURRENT)) Some("CONCURRENT") else None,
    if (spliterator.hasCharacteristics(Spliterator.DISTINCT)) Some("DISTINCT") else None,
    if (spliterator.hasCharacteristics(Spliterator.IMMUTABLE)) Some("IMMUTABLE") else None,
    if (spliterator.hasCharacteristics(Spliterator.NONNULL)) Some("NONNULL") else None,
    if (spliterator.hasCharacteristics(Spliterator.ORDERED)) Some("ORDERED") else None,
    if (spliterator.hasCharacteristics(Spliterator.SIZED)) Some("SIZED") else None,
    if (spliterator.hasCharacteristics(Spliterator.SORTED)) Some("SORTED") else None,
    if (spliterator.hasCharacteristics(Spliterator.SUBSIZED)) Some("SUBSIZED") else None
  ).flatten.mkString(", "))
}

Créé à partir de java.util.Iterator

Avec spécification de taille

Le deuxième argument de Spliterators.spliterator est la taille de l'itérateur, et le troisième argument est les caractéristiques spécifiées en plus. Par exemple, si le niveau application garantit que l'élément n'est pas «nul», vous pouvez spécifier «NONNULL» comme troisième argument. Spécifier 0 n'ajoute aucune caractéristique.

scala> val iterator = new java.util.Iterator[Int] {
     |   var i = 0
     |   def hasNext(): Boolean = i < 8
     |   def next(): Int = {
     |     if (i >= 8) throw new NoSuchElementException()
     |     i += 1
     |     i
     |   }
     | }
iterator: java.util.Iterator[Int]{def i: Int; def i_=(x$1: Int): Unit} = $anon$1@1d6dc2b8

scala> val spliterator = Spliterators.spliterator(iterator, 8, 0)
spliterator: java.util.Spliterator[Int] = java.util.Spliterators$IteratorSpliterator@5c8e7687

scala> printCharacteristics(spliterator)
SIZED, SUBSIZED

Aucune taille spécifiée

L'itérateur peut avoir un nombre indéterminé d'éléments ou un nombre infini d'éléments. Dans de tels cas, utilisez Spliterators.spliteratorUnknownSize pour créer Spliterator. Le deuxième argument est les caractéristiques que vous spécifiez en plus

scala> val iterator = new java.util.Iterator[Int] {
     |   var i = 0
     |   def hasNext(): Boolean = i < 8
     |   def next(): Int = {
     |     if (i >= 8) throw new NoSuchElementException()
     |     i += 1
     |     i
     |   }
     | }
iterator: java.util.Iterator[Int]{def i: Int; def i_=(x$1: Int): Unit} = $anon$1@1c96bf1e

scala> val spliterator = Spliterators.spliteratorUnknownSize(iterator, 0)
spliterator: java.util.Spliterator[Int] = java.util.Spliterators$IteratorSpliterator@44ba9f25

scala> printCharacteristics(spliterator)

Créé à partir d'un tableau ou d'une collection régulière

Tableau

Si vous créez Spliterator tel qu'il est à partir de ʻArray [Int], vous pouvez créer Spliterator spécialisé pour les tableaux primitifs, donc je l'ai converti en ʻAnyRef (type Java ʻObject`).

scala> val spliterator = Spliterators.spliterator[Int]((1to8).toArray.map(_.asInstanceOf[AnyRef]),0)
spliterator: java.util.Spliterator[Int] = java.util.Spliterators$ArraySpliterator@32ca397b

scala> printCharacteristics(spliterator)
SIZED, SUBSIZED

ArrayList

scala> val collection = new ArrayList[Int]()
collection: java.util.ArrayList[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.ArrayList$ArrayListSpliterator@7d3af2f0

scala> printCharacteristics(spliterator)
ORDERED, SIZED, SUBSIZED

LinkedList

scala> val collection = new LinkedList[Int]()
collection: java.util.LinkedList[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.LinkedList$LLSpliterator@71637a85

scala> printCharacteristics(spliterator)
ORDERED, SIZED, SUBSIZED

HashSet

scala> val collection = new HashSet[Int]()
collection: java.util.HashSet[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.HashMap$KeySpliterator@71daf5d6

scala> printCharacteristics(spliterator)
DISTINCT, SIZED

LinkedHashSet

scala> val collection = new LinkedHashSet[Int]()
collection: java.util.LinkedHashSet[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.Spliterators$IteratorSpliterator@28391cc6

scala> printCharacteristics(spliterator)
DISTINCT, ORDERED, SIZED, SUBSIZED

TreeSet

scala> val collection = new TreeSet[Int]()
collection: java.util.TreeSet[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.TreeMap$KeySpliterator@62b630e0

scala> printCharacteristics(spliterator)
DISTINCT, ORDERED, SIZED, SORTED

PriorityQueue

scala> val collection = new PriorityQueue[Int]()
collection: java.util.PriorityQueue[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.PriorityQueue$PriorityQueueSpliterator@6f75d11b

scala> printCharacteristics(spliterator)
NONNULL, SIZED, SUBSIZED

Collecte parallèle

CopyOnWriteArrayList

scala> val collection = new CopyOnWriteArrayList[Int]()
collection: java.util.concurrent.CopyOnWriteArrayList[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.Spliterators$ArraySpliterator@5a931c02

scala> printCharacteristics(spliterator)
IMMUTABLE, ORDERED, SIZED, SUBSIZED

CopyOnWriteArraySet

scala> val collection = new CopyOnWriteArraySet[Int]()
collection: java.util.concurrent.CopyOnWriteArraySet[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.Spliterators$ArraySpliterator@ca024d8

scala> printCharacteristics(spliterator)
DISTINCT, IMMUTABLE, SIZED, SUBSIZED

ConcurrentSkipListSet

scala> val collection = new ConcurrentSkipListSet[Int]()
collection: java.util.concurrent.ConcurrentSkipListSet[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.concurrent.ConcurrentSkipListMap$KeySpliterator@7e003cf0

scala> printCharacteristics(spliterator)
CONCURRENT, DISTINCT, NONNULL, ORDERED, SORTED

ConcurrentLinkedQueue

scala> val collection = new ConcurrentLinkedQueue[Int]()
collection: java.util.concurrent.ConcurrentLinkedQueue[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.concurrent.ConcurrentLinkedQueue$CLQSpliterator@ffbdb79

scala> printCharacteristics(spliterator)
CONCURRENT, NONNULL, ORDERED

LinkedBlockingQueue

scala> val collection = new LinkedBlockingQueue[Int]()
collection: java.util.concurrent.LinkedBlockingQueue[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.concurrent.LinkedBlockingQueue$LBQSpliterator@d57ba2a

scala> printCharacteristics(spliterator)
CONCURRENT, NONNULL, ORDERED

LinkedTransferQueue

scala> val collection = new LinkedTransferQueue[Int]()
collection: java.util.concurrent.LinkedTransferQueue[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.concurrent.LinkedTransferQueue$LTQSpliterator@2977084e

scala> printCharacteristics(spliterator)
CONCURRENT, NONNULL, ORDERED

PriorityBlockingQueue

scala> val collection = new PriorityBlockingQueue[Int]()
collection: java.util.concurrent.PriorityBlockingQueue[Int] = []

scala> (1 to 8).foreach(collection.add)

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.concurrent.PriorityBlockingQueue$PBQSpliterator@1fd97710

scala> printCharacteristics(spliterator)
NONNULL, SIZED, SUBSIZED

Modèles avec des restrictions spéciales

Collections.singletonList

Une liste immuable avec un seul élément.

scala> val collection = Collections.singletonList(1)
collection: java.util.List[Int] = [1]

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.Collections$2@56625ce9

scala> printCharacteristics(spliterator)
DISTINCT, IMMUTABLE, NONNULL, ORDERED, SIZED, SUBSIZED

Collections.singlton

Un ensemble immuable avec un seul élément.

scala> val collection = Collections.singleton(1)
collection: java.util.Set[Int] = [1]

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.Collections$2@60d501f6

scala> printCharacteristics(spliterator)
DISTINCT, IMMUTABLE, NONNULL, ORDERED, SIZED, SUBSIZED

Collections.emptyList

C'est une liste de ciel immuable.

scala> val collection = Collections.emptyList[Int]()
collection: java.util.List[Int] = []

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.Spliterators$EmptySpliterator$OfRef@170f6972

scala> printCharacteristics(spliterator)
SIZED, SUBSIZED

Collections.emptySet

C'est un ciel immuable.

scala> val collection = Collections.emptySet[Int]()
collection: java.util.Set[Int] = []

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.Spliterators$EmptySpliterator$OfRef@170f6972

scala> printCharacteristics(spliterator)
SIZED, SUBSIZED

Collections.emptySortedSet

Un ciel immuable SortedSet.

scala> val collection = Collections.emptySortedSet[Int]()
collection: java.util.SortedSet[Int] = []

scala> val spliterator = collection.spliterator()
spliterator: java.util.Spliterator[Int] = java.util.TreeMap$KeySpliterator@d5ce7bb

scala> printCharacteristics(spliterator)
DISTINCT, ORDERED, SIZED, SORTED

Spliterators.emptySpliterator

Videz le Spliterator.

scala> val spliterator = Spliterators.emptySpliterator[Int]()
spliterator: java.util.Spliterator[Int] = java.util.Spliterators$EmptySpliterator$OfRef@170f6972

scala> printCharacteristics(spliterator)
SIZED, SUBSIZED

Recommended Posts

Récapitulatif des valeurs renvoyées par la méthode des caractéristiques Spliterator #java
[Java] Gestion des Java Beans dans la chaîne de méthodes
[Java] Appel de méthode dynamique par réflexion du type enum (enum)
L'ordre des modificateurs de méthode Java est fixe
J'ai comparé les caractéristiques de Java et .NET
Résumé du support Java 2018
[Java] Résumé de base de Java non couvert par Progate ~ Partie 1 ~
Résumé des méthodes de lecture de fichiers pour chaque format de fichier Java
[Java] Résumé des expressions régulières
[Java] Résumé des opérateurs (opérateur)
Résumé orienté objet par les débutants (Java)
[Java] Résumé de base de Java non couvert par Progate ~ Partie 2 ・ Liste ~
Le piège que l'implémentation par défaut de l'interface Java 8 apporte
Résumé des bases du langage Java
Valeur médiane de trois valeurs
Résumé de la classe Java Math
Avantages de la méthode statique Java
[Java] Résumé de la syntaxe de contrôle
Résumé du traitement des erreurs Java
[Java] Résumé des modèles de conception
[Java] Résumé des opérations mathématiques
Changer la version de java installée par SDKMAN lors du déplacement de répertoires
L'histoire de ne pas connaître le comportement de String en passant par Java
Concaténer les chaînes renvoyées par des méthodes multi-objets dans Java Stream
[Java] Introduction appropriée par Tenpa people Java Part 0 (règles du code)
[Java] J'ai essayé de faire un labyrinthe par la méthode de creusage ♪
Méthode d'enquête lorsque le processeur du serveur exécutant java est lourd
[Java] Supprimer les éléments de la liste
[Pour les débutants] Résumé du constructeur java
[Édition Java] Histoire de la sérialisation
Résumé du package [Java Silver Study]
Transition d'écran par méthode Post [Java]
Comparaison Java à l'aide de la méthode compareTo ()
[Java] DateTimeFormatter sortie par FormatStyle
À propos du rôle de la méthode initialize
Récapitulatif du problème Java "Pass by Reference"
Résumé de la programmation orientée objet utilisant Java
L'origine des expressions Java lambda
Appelez la super méthode en Java
Vérifiez l'enregistrement MX de l'adresse e-mail avec java et vérifiez le domaine
Implémentation de la méthode de clonage pour Java Record
Mes réflexions sur la méthode d'égalité (Java)
[Java Silver] Résumé des points de modification d'accès
Résumé de la session d’étude interne des recrues [Java]
Obtenez le résultat de POST en Java
Vérifiez le contenu du magasin de certificats Java
Examiner l'utilisation de la mémoire des éléments Java
[Java] Obtenez le jour d'un jour spécifique
[java] Résumé de la gestion des caractères
Résumé de la compréhension de Docker par les débutants ② ~ docker-compose ~
[Java] Résumé personnel des instructions conditionnelles (basique)
[Java] Comment utiliser la méthode toString ()
Comparer les éléments d'un tableau (Java)
[jour: 5] J'ai résumé les bases de Java
Quelles sont les fonctionnalités mises à jour de Java 13
Mesurez facilement la taille des objets Java