Le problème est que le fichier POP.csv est partiellement pourri : il y a des lignes à la fin qui ne sont pas cohérentes (pas les mêmes datas). En plus la regexp de parsing ne fonctionne pas s'il n'y a aucune donnée dans une ligne (que des virgules).
Par ailleurs, les index que tu utilisais n'étaient pas tous correct et donc ça ne prenait pas les données correspondantes. En particulier, les fichiers 2 et 3 référence les pays en anglais, donc on ne pouvait pas utiliser le nom du pays en français comme clef. Au vu de ton code de recherche d'ailleurs, ce sont les noms en anglais qu'il faut prendre comme nom de pays à priori. On peut changer ça facilement en modifiant le dataIndex pour le collect du premier fichier, mais il faudra recherche "France (La)" pour trouver le pays "France" ! Ou alors il faudrait traiter le nom pour virer ce qui se trouve entre parenthèse (par regexp).
Il y a aussi beaucoup de données non utilisable (dans le fichier de surface, il y a des pays non présent dans le premier fichier)
Le code suivant fonctionne globalement (on extrait certains pays, avec leur population et surface), mais il faudrait éventuellement envisager de lire le premier fichier à part (il contient différentes données, nom de pays en 2 langues, code iso639) qui pourraient servir à matcher dans d'autres fichiers, selon les cas.
J'ai aussi modifié le code pour que la population et la surface soit sous forme numérique ce qui est quand même plus logique.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167 public class CountryManager implements Iterable<Country>{ private static final String PROPERTY_SURFACE = "surface"; private static final String PROPERTY_POPULATION = "population"; private static final String PROPERTY_NAME = "name"; final List<Country> countries; public CountryManager() throws IOException { countries = Collections.unmodifiableList(readCountries()); } public Country searchByCountryName(String countryName) throws NoSuchElementException { Country result = null; for (Country country: countries) { if (country.getName().equalsIgnoreCase(countryName)) { result = country; break; } } if (result == null) { throw new NoSuchElementException("Country " + countryName + " does not exists."); } else { return result; } } public List<Country> getCountries() { return countries; } public Iterator<Country> iterator() { return countries.iterator(); } public static void main(String[] args) { try { CountryManager countryManager = new CountryManager(); for(Country country : countryManager) { System.out.println(country); } System.out.println("Search France: " + countryManager.searchByCountryName("France")); } catch (IOException e) { e.printStackTrace(); } } /** * * @param file * nom de fichier * @param lineToSkip * nombre de ligne à ignorer au début du fichier * @param splitString * expression régulière pour découpage de lignes en tableau * @param dataIndex * numéro de la cellule dans le tableau * @param name * nom de la propriété à lire * @param countryIndex * numéro de la cellule qui contient le nom du pays, ou -1 si on * lit les noms de pays * @param map * une map pour stocker le résultat * @throws IOException */ public static void collect(String file, Charset charset, int lineToSkip, String splitString, int dataIndex, String propertyName, int countryIndex, boolean keyDef, Map<String, Map<String, String>> map) throws IOException { try (BufferedReader reader = Files.newBufferedReader(Paths.get(file), charset)) { for (String line = reader.readLine(); line != null; line = reader.readLine()) { if (lineToSkip > 0) { // on saute les lignes au début lineToSkip--; continue; } if ( !line.trim().isEmpty() ) { final String[] data = line.split(splitString); //System.out.println(Arrays.toString(data)); if (dataIndex >= data.length) { /*System.err.println(file+ ": Ligne ignorée (pas assez de données): " + data.length + "<=" + dataIndex + " " + Arrays.toString(data) + " "+line);*/ } else { if (countryIndex >= data.length) { /*System.err.println(file+ ": Ligne ignorée (pas assez de données pour le pays): " + data.length + "<=" + countryIndex + " " + Arrays.toString(data)+ " "+line);*/ } else { String value = data[dataIndex].trim(); String countryKey = data[countryIndex].trim().toLowerCase(); if (keyDef) { final Map<String, String> dataMap = new HashMap<>(); dataMap.put(propertyName, value); map.put(countryKey, dataMap); } else { final Map<String, String> dataMap = map.get(countryKey); if (dataMap != null) { dataMap.put(propertyName, value); } /*else { System.err.println("Country not found: " + data[countryIndex]); }*/ } } } } } } } public static List<Country> readCountries() throws IOException { final Map<String, Map<String, String>> map = new HashMap<>(); collect("country_codes_iso.csv", StandardCharsets.UTF_8, 1, ",", 0, CountryManager.PROPERTY_NAME, 0, true, map); // nom du pays collect("POP.csv", StandardCharsets.ISO_8859_1, 6, ",(?=([^\"]*\"[^\"]*\")*[^\"]*$)", 4, CountryManager.PROPERTY_POPULATION, 3, false, map); // population collect("rawdata_2147.txt", StandardCharsets.UTF_8, 0, "\t", 2, CountryManager.PROPERTY_SURFACE, 1, false, map); // surface return map.values().stream().map(m -> new Country(m.get(CountryManager.PROPERTY_NAME), convertPopulation(m.get(CountryManager.PROPERTY_NAME), m.get(CountryManager.PROPERTY_POPULATION)), convertSurface(m.get(CountryManager.PROPERTY_NAME), m.get(CountryManager.PROPERTY_SURFACE)))) .collect(Collectors.toList()); } private final static DecimalFormat POPULATION_FORMAT = new DecimalFormat("#,##0", DecimalFormatSymbols.getInstance(Locale.US)); private static long convertPopulation(String country, String string) { if ( string!=null ) { string = string.trim().replaceAll("\"",""); if ( !string.isEmpty() ) { try { return (long) POPULATION_FORMAT.parse(string); } catch (ParseException | ClassCastException e) { System.err.println("Erreur dans la population de " + country + ": " + string + " n'est pas un nombre entier."); } } } return 0; } private final static DecimalFormat SURFACE_FORMAT = new DecimalFormat("#,##0", DecimalFormatSymbols.getInstance(Locale.US)); private static long convertSurface(String country, String string) { if ( string!=null ) { string = string.trim().replaceAll("\"",""); if ( !string.isEmpty() ) { try { return (long) SURFACE_FORMAT.parse(string); } catch (ParseException | ClassCastException e) { System.err.println("Erreur dans la surface de " + country + ": " + string + " n'est pas un nombre entier."); } } } return 0; } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 public class Country { private final String name; private final long population; private final long surface; private final static DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#,##0",DecimalFormatSymbols.getInstance(Locale.US)); public Country(String name, long population, long surface) { this.name=name; this.population=population; this.surface=surface; } public String getName() { return name; } public long getPopulation() { return population; } public long getSurface() { return surface; } @Override public String toString() { return "["+name+";pop="+DECIMAL_FORMAT.format(population)+";surface"+DECIMAL_FORMAT.format(surface)+"]"; } }
L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
Nouveau sur le forum ? Consultez Les Règles du Club.
Je te remercie vraiment pour ton aide ! Et ta patience surtout !
J'ai dernière question, lorsque tu recherches par nom le pays tu utilises la méthode "country.getName().equalsIgnoreCase(countryName))"
Mais ca ne fonctionne que pour les String si je ne me trompe pas.., si je veux faire la meme chose avec un long que serait la population par exemple, je devrai utiliser quoi ?
Forcément, equalsIgnoreCase servant à tester l'égalité sans prise en compte de la casse, une notion concernant des caractères, on ne peut pas l'appliquer à les long.
Le problème avec les longs, c'est que si on fait une égalité pure, on risque d'avoir du mal à trouver des résultats. Genre si j'ai trois pays avec 12521245, 8454, 4589212 habitants et que je cherche 303215 habitants j'aurais 0 pays. Il faudrait vraiment avoir du bol ou connaître d'avance la population d'un pays pour avoir une réponse.
Je dirais que pour gérer ce cas, il vaut mieux procéder par intervalle.
Soit intervalle pur, je cherche entre telle et telle valeur :
Toutefois cela pose un problème : on peut avoir plusieurs pays avec la même population, à fortiori, plusieurs pays dans le même intervalle. On peut modifier pour récupérer plusieurs pays :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 public Country searchByPopulation(long min, long max) throws NoSuchElementException { Country result = null; for (Country country: countries) { if (min<=country.getPopulation() && country.getPopulation()<=max) { result = country; break; } } if (result == null) { throw new NoSuchElementException("No country found with population between " + min + " and " + max ); } else { return result; } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 public Set<Country> searchByPopulation(long min, long max) throws NoSuchElementException { Set<Country> result = new HashSet<>(); for (Country country: countries) { if (min<=country.getPopulation() && country.getPopulation()<=max) { result.add(country); } } if (result.isEmpty() { throw new NoSuchElementException("No country found with population between " + min + " and " + max ); } else { return Collections.unmodifiableSet(result); } }
Soit par tranche, soit fixes, genre intervalles de 10000, ou progressives, <10000, entre 10000 et 50000, entre 50000 et 250000, entre 250000 et 500000, etc.
Pour le premier cas, il suffit de faire :
Ainsi quand on cherche un pays pour une tranche
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 public Set<Country> searchByPopulation(long population) throws NoSuchElementException { int min = 10000*(population/10000); int max = min+10000; Set<Country> result = new HashSet<>(); for (Country country: countries) { if (min<=country.getPopulation() && country.getPopulation()<max) { result.add(country); } } if (result.isEmpty() { throw new NoSuchElementException("No country found with population in bracket [" + min + ", " + max+"[" ); } else { return Collections.unmodifiableSet(result); } }
On peut même rendre la tranche paramétrable :
pour des tranches de tailles progressives, il faudra faire
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 public Set<Country> searchByPopulation(long population, int rangeWidth) throws NoSuchElementException { if ( rangeWidth<=0 ) throw new IllegalArgumentException("Incorrect value for range width"); int min = rangeWidth*(population/rangeWidth); int max = min+rangeWidth; Set<Country> result = new HashSet<>(); for (Country country: countries) { if (min<=country.getPopulation() && country.getPopulation()<max) { result.add(country); } } if (result.isEmpty() { throw new NoSuchElementException("No country found with population in range [" + min + ", " + max+"[" ); } else { return Collections.unmodifiableSet(result); } }
ou par boucle, ce qui permet de rendre paramétrable les tranches :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 public Set<Country> searchByPopulation(long population) throws NoSuchElementException { Set<Country> result = new HashSet<>(); int min; int max; if ( population<10000 ) { min=0; max=10000; } else if ( population<50000 ) { min=10000; max=50000; } else if ( population < 250000 ) { min=50000; max=250000; } else { min=250000; max=Integer.MAX_VALUE; } for (Country country: countries) { if (min<=country.getPopulation() && country.getPopulation()<max) { result.add(country); } } if (result.isEmpty() { throw new NoSuchElementException("No country found with population in range [" + min + ", " + max+"[" ); } else { return Collections.unmodifiableSet(result); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 public Set<Country> searchByPopulation(long population, int...ranges) throws NoSuchElementException { // on vérifie que les tranches sont bien ordonnées int[] sorted = Arrays.copyOf(ranges, ranges.length); Arrays.sort(sorted); if ( !Arrays.equals(sorted,ranges)) { throw new IllegalArgumentException(); } int min=0; int max=Integer.MAX_VALUE; for(int i : ranges) { if ( population < i ) { max=i; break; } min=i; } Set<Country> result = new HashSet<>(); for (Country country: countries) { if (min<=country.getPopulation() && country.getPopulation()<max) { result.add(country); } } if (result.isEmpty() { throw new NoSuchElementException("No country found with population in range [" + min + ", " + max+"[" ); } else { return Collections.unmodifiableSet(result); } }
L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
Nouveau sur le forum ? Consultez Les Règles du Club.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager