[Java] Convertir 1 en N liste en carte

introduction

Par exemple, lorsque vous souhaitez traiter le résultat extrait en joignant deux tables parent et enfant de la base de données pour chaque clé. Vous pouvez le traiter sous forme de liste, mais il est préférable de le regrouper par clé, n'est-ce pas? (Personnellement, je l'aime car il améliore la lisibilité. S'il y a un problème de performance, il ne peut pas être résolu.) Cette fois, après l'acquisition par lots avec une liste côte à côte, essayez de convertir en Map (clé: table parent, valeur: table enfant).

supposition

ER

Chef de département

Maître des employés

Si vous obtenez cela par jointure interne, ce sera comme ça. ↓

select_all.sql


select *
du Département Master
maître des employés de jointure interne utilisant l'ID de service;

Image du résultat d'acquisition (Liste <résultat>) ↓

département Employé
Département 1 Employé 1
Département 1 Employé 2
Département 2 Employé 3
Département 2 Employé 4
Département 2

Le but de ce temps est de convertir cela en "Mapper <département, Liste <employé >>" avec le département comme clé et l'employé comme valeur.

la mise en oeuvre

environnement

Ce que j'ai fait

--DemoService: processus principal --DbMapper: en fait un mappeur OR tel que Mybatis. --DbMapperImpl: DbMapper implémenté pour les tests. --Result: Stocke le résultat de select_all.sql --Département: Table des départements --Employé: table des employés

Classe de service

Pour le moment, j'ai créé deux méthodes list2Map7 de ** Java7 ** version et ** Java8 (Stream API) **. Les résultats devraient être les mêmes pour les deux. Après tout, l'implémentation avec Stream API a une petite quantité de code et est facile à voir. Je ne veux vraiment pas implémenter quoi que ce soit qui n'ait rien à voir avec la logique métier. Si vous faites de votre mieux, list2Map8 peut être plus facile à voir. Cependant, il semble que le code moins lisible augmentera en plus de la classe Service.

DemoService.java


package com.example.demo;

import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class DemoService {

	@Autowired
	DbMapper mapper;

	public void execute(String[] args) {
		log.info("### START ###");
		// select from DB
		List<Result> list = mapper.select();
		//Contenu extrait
		list.forEach(System.out::println);
		// List ⇒ LinkedHashMap
		Map<Department, List<Employee>> map = list2Map8(list);
		System.out.println();
		//Résultat de la conversion de sortie
		for (Map.Entry<Department, List<Employee>> entry : map.entrySet()) {
			System.out.println("Key:" + entry.getKey());
			entry.getValue().forEach(e -> System.out.println("    Value:" + e));
		}
		log.info("### END ###");
	}

	/**
	 *Conversion de liste⇒Map(java7Ver).
	 * 
	 * @param list
	 * @return
	 */
	private Map<Department, List<Employee>> list2Map7(List<Result> list) {
		if (list.isEmpty()) {
			return Collections.emptyMap();
		}
		Map<Department, List<Employee>> map = new LinkedHashMap<>();
		//Dernière clé
		Department prevDep = null;
		List<Employee> tempList = null;
		for (Result result : list) {
			Department dep = result.getDepartment();
			//Si la clé change
			if (!dep.equals(prevDep)) {
				//Initialiser la liste de valeurs
				tempList = new ArrayList<>();
				//Ajouté à la carte avec les valeurs initialisées(Définir la référence à la carte)
				map.put(dep, tempList);
				//Utilisez cette touche comme clé précédente
				prevDep = dep;
			}
			//Ajouter une valeur à tempList qui fait référence à la carte
			tempList.add(result.getEmployee());
		}
		return map;
	}

	/**
	 *Conversion de liste⇒Map(java8Ver).
	 * 
	 * @param list
	 * @return
	 */
	private Map<Department, List<Employee>> list2Map8(List<Result> list) {
		// List(valeur)⇒Map(キー、valeur)Conversion en
		Map<Department, List<Employee>> ret = list.stream()
				.collect(Collectors.groupingBy(Result::getDepartment,
				LinkedHashMap::new, Collectors.mapping(Result::getEmployee, Collectors.toList())));
		return ret;
	}
}

J'utilise ** LinkedHashMap ** pour conserver l'ordre d'acquisition. Il n'est pas conservé dans HashMap. (Merci pour votre commentaire et l'amélioration de la méthode de conversion.)

Interface DbMapper

En fait, c'est comme utiliser Mybatis ou OR mapper.

DbMapper.java


package com.example.demo;

import java.util.List;
import org.springframework.stereotype.Component;

@Component
public interface DbMapper {
	List<Result> select();
}

Classe DbMapperImpl

Renvoie des données pour le débogage.

DbMapperImpl.java


package com.example.demo;

import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Component;

@Component
public class DbMapperImpl implements DbMapper {
	@Override
	public List<Result> select() {
		List<Result> list = new ArrayList<>();
		list.add(getResult(1, 101));
		list.add(getResult(1, 102));
		list.add(getResult(2, 203));
		list.add(getResult(3, 304));
		list.add(getResult(3, 305));
		list.add(getResult(3, 306));
		return list;
	}

	private Result getResult(int did, int eid) {
		Department department = new Department();
		department.setDepartmentId(did);
		department.setDepartmentName("système" + did + "Division");

		Employee employee = new Employee();
		employee.setEmployeeId(eid);
		employee.setName("Yamada" + eid + "Ro");
		employee.setDepartmentId(department.getDepartmentId());

		Result result = new Result(department, employee);
		return result;
	}
}

Classe de résultat

Objet dans lequel le résultat SELECT de la base de données est stocké en premier.

Result.java


package com.example.demo;

import lombok.Data;

@Data
public class Result {
	private Department department;
	private Employee employee;

	public Result() {
	}

	public Result(Department department, Employee employee) {
		this.department = department;
		this.employee = employee;
	}
}

Classe de département

Chef de département. @Data de Lombok remplace le hashcode et est égal à. Il en va de même pour le maître des employés. Selon la situation, si cela représente réellement un enregistrement dans la table, alors PK est le seul champ à remplacer. Dans ce cas, créez le vôtre sans utiliser @Data. Le remplacement est requis car LinkedHashMap (HashMap) est utilisé.

Department.java


package com.example.demo;

import lombok.Data;

@Data
public class Department {
	private Integer departmentId;
	private String departmentName;
}

Classe d'employé

Maître des employés.

Employee.java


package com.example.demo;

import lombok.Data;

@Data
public class Employee {
	private Integer employeeId;
	private String name;
	private Integer departmentId;
}

Résultat d'exécution

Il est correctement converti en une carte pour chaque clé (département).

Résultat d'exécution


Result(department=Department(departmentId=1, departmentName=Section système 1), employee=Employee(employeeId=101, name=Yamada 101ro, departmentId=1))
Result(department=Department(departmentId=1, departmentName=Section système 1), employee=Employee(employeeId=102, name=102ro Yamada, departmentId=1))
Result(department=Department(departmentId=2, departmentName=Section système 2), employee=Employee(employeeId=203, name=Yamada 203ro, departmentId=2))
Result(department=Department(departmentId=3, departmentName=Section système 3), employee=Employee(employeeId=304, name=Yamada 304ro, departmentId=3))
Result(department=Department(departmentId=3, departmentName=Section système 3), employee=Employee(employeeId=305, name=Yamada 305ro, departmentId=3))
Result(department=Department(departmentId=3, departmentName=Section système 3), employee=Employee(employeeId=306, name=Yamada 306ro, departmentId=3))

Key:Department(departmentId=1, departmentName=Section système 1)
    Value:Employee(employeeId=101, name=Yamada 101ro, departmentId=1)
    Value:Employee(employeeId=102, name=102ro Yamada, departmentId=1)
Key:Department(departmentId=2, departmentName=Section système 2)
    Value:Employee(employeeId=203, name=Yamada 203ro, departmentId=2)
Key:Department(departmentId=3, departmentName=Section système 3)
    Value:Employee(employeeId=304, name=Yamada 304ro, departmentId=3)
    Value:Employee(employeeId=305, name=Yamada 305ro, departmentId=3)
    Value:Employee(employeeId=306, name=Yamada 306ro, departmentId=3)

Épilogue

Lombok est pratique, n'est-ce pas?

Recommended Posts

[Java] Convertir 1 en N liste en carte
Pour les débutants Java: List, Map, Iterator / Array ... Comment convertir?
[Java] [ibatis] Comment obtenir des enregistrements de relation 1 à N avec List <Map <>>
[Java] Comment utiliser Map
Comment utiliser Java Map
Comment convertir la base Java
[Java] Convertir ArrayList en tableau
Exemple de code pour convertir List en List <String> dans Java Stream
Flux appris (je veux convertir la liste en carte <Integer, List>)
Convertir la carte <K, V1> en carte <K, V2> (Convertir la valeur de la carte)
JAVA (Carte)
[Java] Comment utiliser List [ArrayList]
[Android] Convertir le code Java Android en Kotlin
[Java] Conversion d'un tableau à une liste
Conversion de liste Java8 avec Stream map
[Java] Convertit un tableau en ArrayList * Attention
[Android] Convertissez Map en JSON à l'aide de GSON avec Kotlin et Java
[Java] Obtenir des éléments List / Map avec Iterator
[Java] Comment ajouter des données à la liste (add, addAll)
Convertir toutes les applications Android (Java) en Kotlin
Convertir l'heure UTC Java en heure JST
[Java] Convertit null du type Object en type String
Remplacez List <Optional <T >> par Optional <List <T >> en Java
Convertir des fichiers SVG en fichiers PNG en Java
[Java] Map # merge est difficile à comprendre.
Liste, ensemble, carte
Mémorandum Java (liste)
Clonez la liste Java.
Tableau / liste / carte
[Java] Comparaison de cartes
[Java] Introduction à Java
Introduction à Java
[Java] De deux listes à une liste de tableaux
[Java] Convertit le code DB en valeur de code à l'aide d'énum
Convertir Json en List <T> tel quel
Convertir les beans imbriqués Java au format aaa.bbb [0] .ccc
Lancez Docker à partir de Java pour convertir des documents Office en PDF
<java> Lire le fichier Zip et le convertir directement en chaîne
[Java] Convertir la version PDF
Maîtriser Kotlin ~ Convertir un fichier Java en fichier Kotlin Road to Graduation ~ Partie 3
Convertir l'énumération Java et JSON vers et depuis Jackson
Traitement des listes à comprendre avec des images - java8 stream / javaslang-
Changements de Java 8 à Java 11
Somme de Java_1 à 100
Comment utiliser Map
java: Comment écrire une liste de types génériques [Note]
[Java] Convertit les chaînes de caractères en majuscules / minuscules (AOJ⑨ --swap majuscules / minuscules)
[Java] Connectez-vous à MySQL
A propos de la liste des baies Java
Améliorations de Kotlin à Java
Pour les applications Java, convertissez des documents Word (DOC / DOCX) en PDF
De Java à Ruby !!
Bibliothèque de cartes bidirectionnelles Java
Maîtriser Kotlin ~ Convertir un fichier Java en fichier Kotlin Road to Graduation ~ Partie 1
Comment convertir A en A et A en A en utilisant le produit logique et la somme en Java
Comment convertir un fichier en tableau d'octets en Java