Dernière fois: Java8 pour démarrer maintenant ~ for Each et expression lambda ~
Vient ensuite l'édition Stream API.
Il s'agit d'une API introduite à partir de Java8 qui peut décrire le traitement (opération d'agrégation) des tableaux et des collections. Suivez la procédure ci-dessous pour un ensemble d'éléments.
C'est complètement différent de la façon d'écrire vers Java7, je vais donc le résumer à l'aide d'un exemple.
order.csv
BBJ001,300
AES010,20
BBJ005,100
BBJ001,50
DIH999,10
AES010,150
item.csv
BBJ001,Stylo bille noir
BBJ005,Stylo bille rouge
AES010,la gomme
order_collected.csv
DIH999,,10
BBJ005,Stylo bille rouge,100
BBJ001,Stylo bille noir,300
BBJ001,Stylo bille noir,50
AES010,la gomme,20
AES010,la gomme,150
Si vous déposez cet exemple dans votre code, je pense que ce serait comme ça.
Stream <String> java.nio.file.Files # lines (Path)
pour générer un Stream avec toutes les lignes du fichier.
Avant Java7, Reader etc. étaient générés et lus un par un.
Lecture de fichiers de la version Java 7
BufferedReader reader = new BufferedReader(new FileReader("files/stream/item.csv"));
String line = null;
while ((line = reader.readLine()) != null) {
//Traitement divers pour une ligne
}
Maintenant ça.
Lecture du fichier de version de l'API Stream
Stream<String> itemStream = Files.lines(Paths.get("files/stream/item.csv"));
Décomposez chaque élément du Stream créé à l'étape précédente.
Stream<String[]> itemStream2 = itemStream .map(line -> line.split(","));
<R> Stream<R> map(Function<? super T,? extends R> mapper)
L'opération intermédiaire map '' renvoie le Stream résultant de l'application de l'argument expression lambda à chaque élément du Stream. Cette fois, nous passons l'expression lambda
line-> line.split (",") ``.
Traitez line.split (",")
pour chaque élément line
de Stream <String> itemStream
et flux de type Stream <String []>
A été généré.
BBJ001,Stylo bille noir// ⇒ [BBJ001,Stylo bille noir]
BBJ005,Stylo bille rouge// ⇒ [BBJ005,Stylo bille rouge]
・ ・ ・
L'important est que les ** opérations intermédiaires de flux renvoient Stream **. Les opérations intermédiaires et les opérations de terminaison peuvent être effectuées sur les résultats des opérations intermédiaires.
Comme il est difficile de gérer le Stream tel qu'il figure dans l'attribution du nom de produit dans la procédure ultérieure, convertissez-le en Map.
Map<String, String> items = itemStream2.collect(Collectors.toMap(item -> item[0], item -> item[1]));
<R,A> R collect(Collector<? super T,A,R> collector)
L'opération de terminaison collect '' renvoie le résultat de l'application d'une certaine règle (Collector) à chaque élément de Stream. Les règles fréquemment utilisées sont disponibles dans [
Collectors``](https://docs.oracle.com/javase/jp/8/docs/api/java/util/stream/Collectors.html).
Ici, le collecteur toMap (<expression Lambda qui crée une clé de carte>, <expression Lambda qui crée une valeur de carte>)
qui renvoie une carte est utilisé.
Puisque itemStream2 est un Stream de `` String [] '', nous avons généré une carte avec le 0e élément du tableau comme clé et le 1er élément comme valeur.
** Opérations intermédiaires de Stream return Stream **, vous pouvez donc écrire dans une chaîne de la création du Stream à la conversion de la carte.
//Lire le fichier de nom de produit
Map<String, String> items = Files.lines(Paths.get("files/stream/item.csv") // Stream<String>
//Convertir une ligne de fichier en tableau(Préparation de la carte)
.map(line -> line.split(",")) // Stream<String[]>
//Convertir en carte
.collect(Collectors.toMap(item -> item[0], item -> item[1])); // Map<String, String>
Ensuite, nous commencerons le traitement du fichier de commande. C'est le même que le nom de produit maître jusqu'au point où une ligne de données est décomposée.
Stream<String> orderStream = Files.lines(Paths.get("files/stream/order.csv"))
Stream<OrderDto> orderStream2 = orderStream
//Convertir une ligne de fichier en tableau(Préparation au Dto)
.map(line -> line.split(","))
//Convertir le tableau en Dto de livraison
.map(array -> makeOrder(array));
Après la séparation avec ",", je l'ai mappé à OrderDto avec makeOrder (String [])
.
private static OrderDto makeOrder(String[] array) {
OrderDto order = new OrderDto();
int idx = 0;
order.setItemCode(array[idx++]);
order.setOrderNum(Integer.parseInt(array[idx++]));
return order;
}
Trier par ordre croissant du code produit.
Stream<OrderDto> orderStream3 = orderStream2.sorted((item1, item2) -> item1.getItemCode().compareTo(item2.getItemCode()));
Stream<T> sorted(Comparator<? super T> comparator)
Comparator
définit les règles de comparaison entre les objets C'est une interface fonctionnelle.
Si vous implémentez l'interface Comparable
, elle n'a pas d'arguments` Vous pouvez également utiliser `` sorted () ''.
Vous pouvez définir un ordre de tri par défaut dans l'interface Comparable '' et le redéfinir de manière concise dans une expression lambda en utilisant
Comparator '' si nécessaire.
Recherchez dans la carte des produits par code de produit, et si cela correspond, indiquez le nom du produit et, s'il ne correspond pas, remplissez les caractères vides.
Stream<OrderDto> orderStream4 = orderStream2.map(order -> {
order.setItemName(Optional.ofNullable(items.get(order.getItemCode())).orElse(""));
return order;
});
Utilisez à nouveau la carte. Facultatif n'est pas expliqué en détail ici, mais il est utilisé comme fonction pour déterminer la valeur par défaut lorsqu'elle est Null.
Maintenant que les données sont complètes, exportez-les dans un fichier.
try (BufferedWriter writer = new BufferedWriter(new FileWriter("files/stream/order_collected.csv")) ) {
orderList.forEach(order -> {
try {
writer.write(makeLine(order));
writer.newLine();
} catch (IOException e) {e.printStackTrace();return;}
});
}
void forEach(Consumer<? super T> action)
L'opération de terminaison `` forEach '' utilisée dans l'explication de l'expression lambda la dernière fois exécute l'opération spécifiée par l'argument pour chaque élément.
public class StreamMain {
public static void main(String[] args) {
try (Stream<String> orderStream = Files.lines(Paths.get("files/stream/order.csv"));
Stream<String> itemStream = Files.lines(Paths.get("files/stream/item.csv"))){
//Lire le fichier de commande
Map<String, String> items = itemStream
//Convertir une ligne de fichier en tableau(Préparation de la carte)
.map(line -> line.split(","))
//Convertir en carte
.collect(Collectors.toMap(item -> item[0], item -> item[1]));
//Lire le fichier de nom de produit
Stream<OrderDto> orderList = orderStream
//Convertir une ligne de fichier en tableau(Préparation au Dto)
.map(line -> line.split(","))
//Convertir le tableau en Dto de livraison
.map(array -> makeOrder(array))
//Trier
.sorted((item1, item2) -> item1.getItemCode().compareTo(item2.getItemCode()))
//correspondant à
.map(order -> {
order.setItemName(Optional.ofNullable(items.get(order.getItemCode())).orElse(""));
return order;
});
//production
try (BufferedWriter writer = new BufferedWriter(new FileWriter("files/stream/order_collected.csv")) ) {
orderList.forEach(order -> {
try {
writer.write(makeLine(order));
writer.newLine();
} catch (IOException e) {e.printStackTrace();return;}
});
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static String makeLine(OrderDto order) {
StringBuilder line = new StringBuilder();
line.append(order.getItemCode());
line.append(',');
line.append(order.getItemName());
line.append(',');
line.append(order.getOrderNum());
return line.toString();
}
private static OrderDto makeOrder(String[] array) {
OrderDto order = new OrderDto();
int idx = 0;
order.setItemCode(array[idx++]);
order.setOrderNum(Integer.parseInt(array[idx++]));
return order;
}
}
En résolvant l'exemple, j'ai d'abord organisé la procédure.
- Lire la fiche produit
- Divisez une ligne en code produit et nom de produit
- clé: code produit, valeur: carte du nom du produit
Probablement, dans le code Java7 ou antérieur, même la carte est générée au moment de la boucle for pour lire le nom de produit principal.
Java7
for (/*Ensemble d'éléments*/) {
//Traitement divers pour un élément
}
À propos, l'API Stream fonctionne sur un ensemble d'éléments.
Les opérations typiques sont map '' (convertir un élément en un autre élément),
filter '' (extraire celui qui remplit les conditions des éléments / inutilisé cette fois), `` trié '' Par exemple, `(éléments de tri).
De plus, comme la valeur de retour de l'opération intermédiaire est Stream, il convient de créer d'abord un ensemble d'éléments puis de fonctionner en continu.
Java8
Stream obj = //Convertir un ensemble d'éléments en Stream
//Conversion d'éléments dans obj
.map(/*Règles de conversion*/)
//Filtration
.filter(/*Règles d'extraction*/);
Lors de l'utilisation de l'API Stream, il semble que vous deviez penser à la procédure afin qu'elle soit une combinaison d'opérations simples sur les éléments.
L'article suivant a été très utile. Écrire du code de type Java8 en Java8
Je voulais trouver la quantité totale de commande pour chaque code produit, mais j'ai abandonné car je ne savais pas comment l'écrire correctement. Je vais laisser le code commémoratif pour la version forcée, alors faites-le moi savoir si vous avez de bonnes idées.
//Lire le fichier de nom de produit
Stream<OrderDto> orderList = orderStream
//Convertir une ligne de fichier en tableau(Préparation au Dto)
.map(line -> line.split(","))
//Convertir le tableau en Dto de livraison
.map(array -> makeOrder(array));
//Regrouper par code produit pour l'agrégation
Map<String, List<OrderDto>> grouping = orderList.collect(Collectors.groupingBy(order->order.getItemCode()));
//Additionner la quantité commandée pour chaque élément groupé
orderList = grouping.values()
.stream()
.map(orders->{
//Ramassez l'un des éléments
OrderDto order = orders.stream().findAny().get();
//Stocker le nombre total de tous les éléments dans la quantité commandée
order.setOrderNum(orders.stream().mapToInt(oo ->oo.getOrderNum()).sum());
return order;
})
//Trier
.sorted((item1, item2) -> item1.getItemCode().compareTo(item2.getItemCode()))
//Définir le nom du produit
.map(order -> {
order.setItemName(Optional.ofNullable(items.get(order.getItemCode())).orElse(""));
return order;
});
Recommended Posts