Double condition pour une double boucle
Résolu/Fermé
TempsMort0
Messages postés
43
Date d'inscription
mardi 22 janvier 2013
Statut
Membre
Dernière intervention
1 août 2018
-
5 juin 2018 à 17:14
TempsMort0 Messages postés 43 Date d'inscription mardi 22 janvier 2013 Statut Membre Dernière intervention 1 août 2018 - 14 juin 2018 à 18:04
TempsMort0 Messages postés 43 Date d'inscription mardi 22 janvier 2013 Statut Membre Dernière intervention 1 août 2018 - 14 juin 2018 à 18:04
A voir également:
- Double condition pour une double boucle
- Double ecran - Guide
- Whatsapp double sim - Guide
- Double appel - Guide
- Double authentification google - Guide
- Double boot - Guide
2 réponses
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 020
Modifié le 5 juin 2018 à 20:43
Modifié le 5 juin 2018 à 20:43
Bonjour,
Tu utilises trop les scriptlets(code entre
La JSP c'est fait pour afficher des données mais les calculs devraient être fait dans des classes.
Ici il te faudrait probablement une méthode dans ton code Java qui ressemblerait à ça :
Ta double boucle serait alors quelque chose comme ça :
Remarque : il existe aussi d'autres manières d'écrire des JSP pour supprimer complètement les scriptlets et le code Java. Par exemple avec la JSTL ça ressemblerait à ceci :
Tu utilises trop les scriptlets(code entre
<% %>) et pas assez tes classes Java.
La JSP c'est fait pour afficher des données mais les calculs devraient être fait dans des classes.
Ici il te faudrait probablement une méthode dans ton code Java qui ressemblerait à ça :
public static SortedMap<Character, SortedSet<Outil>> sortByInitials(Collection<Outil> outils) { return outils.stream().collect(Collectors.groupingBy(outil -> Character.toLowerCase(outil.getDesignation().charAt(0)), TreeMap::new, Collectors.toCollection(TreeSet::new))); }
Ta double boucle serait alors quelque chose comme ça :
<% for (Entry<Character, List<Outil>> entry : sortByInitials(outils)) { %> <h2><%= entry.getKey() %></h2> <ul> <% for (Outil outil : entry.getValue()) { %> <li><%= outil.getDesignation()%></li> <% } %> </ul> <% } %>
Remarque : il existe aussi d'autres manières d'écrire des JSP pour supprimer complètement les scriptlets et le code Java. Par exemple avec la JSTL ça ressemblerait à ceci :
<c:forEach var="entry" items="${sortByInitials(outils)}"> <h2><c:out value="${entry.key}"/></h2> <ul> <c:forEach var="outil" items="${entry.value}"> <li><c:out value="${outil.designation}"/></li> </c:forEach> </ul> </c:forEach>
TempsMort0
Messages postés
43
Date d'inscription
mardi 22 janvier 2013
Statut
Membre
Dernière intervention
1 août 2018
7 juin 2018 à 12:51
7 juin 2018 à 12:51
Mmh maintenant la List conso ne contient plus que 2 éléments, alors que le fichier en contient 379 en comptant seulement les items.
On peut voir de quoi est remplie la List :
Désolé pour ces posts longs mais je suis perdu sur ce coup, je peux faire des tests pour mener à trouver des solutions.. parce que là je ne vois pas..
On peut voir de quoi est remplie la List :
Désolé pour ces posts longs mais je suis perdu sur ce coup, je peux faire des tests pour mener à trouver des solutions.. parce que là je ne vois pas..
<%@ page import="pac.bdd.beans.Consommable" %> <%@ page import="pac.cmd.CommandeStock" %> <%@ page import="static pac.cmd.CommandeStock.sortByInitials" %> <%@ page import="java.util.*" %> <%@include file="../ihm/miseEnPage1.jsp" %> <%@ page contentType="text/html; charset=UTF-8" %> <% String erreur= (String)request.getAttribute("erreur"); if(erreur!= null) out.println("<div class=\"messerreur\">"+erreur+"</div>"); List<Consommable> conso = (List<Consommable>) request.getAttribute("conso"); %> <div class="middle"> <div class="main_content"> <div class="stock_container"> <p><%=conso.size()%></p> <% for (Map.Entry<Character, SortedSet<Consommable>> entry : sortByInitials(conso).entrySet()) { %> <h2><%= entry.getKey() %></h2> <ul> <% for (Consommable consommable : entry.getValue()) { %> <li><%= consommable.getDesignation()%></li> <% } %> </ul> <% } %> </div> </div> </div> <jsp:include page="../ihm/miseEnPage2.jsp" />
package pac.cmd; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import pac.bdd.beans.Consommable; import javax.servlet.http.HttpServletRequest; import java.io.FileInputStream; import java.io.UnsupportedEncodingException; import java.util.*; import java.util.stream.Collectors; public class CommandeStock implements Commande { private static final String STOCK_FILE_NAME = "C:\\Users\\lomoc\\Cours\\S4\\JSP\\webapps\\Actemium\\WEB-INF\\stock.xls"; private final String next; public CommandeStock(String next) { this.next = next; } public String execute(HttpServletRequest req) throws UnsupportedEncodingException { List<Consommable> conso = readExcelStock(); req.setAttribute("conso", conso); req.setCharacterEncoding("UTF-8"); req.getServletContext().getRequestDispatcher("/WEB-INF/stock.jsp"); return next; } private static List<Consommable> readExcelStock() { List<Consommable> conso = new ArrayList<>(); try (FileInputStream fis = new FileInputStream(STOCK_FILE_NAME); Workbook wb = WorkbookFactory.create(fis)) { Sheet sh = wb.getSheet("STOCK"); int noOfRows = sh.getLastRowNum(); for (int i = 1; i < noOfRows; i++) { Row row = sh.getRow(i); String designation = row.getCell(0).getStringCellValue(); if (designation.isEmpty()) continue; conso.add(new Consommable( sh.getRow(i).getCell(0).toString(), sh.getRow(i).getCell(1).toString(), sh.getRow(i).getCell(2).toString(), sh.getRow(i).getCell(3).toString(), sh.getRow(i).getCell(4).toString(), sh.getRow(i).getCell(5).toString(), sh.getRow(i).getCell(6).toString(), sh.getRow(i).getCell(0).toString(), sh.getRow(i).getCell(8).toString(), sh.getRow(i).getCell(9).toString(), sh.getRow(i).getCell(10).toString(), sh.getRow(i).getCell(11).toString(), sh.getRow(i).getCell(12).toString(), sh.getRow(i).getCell(13).toString(), sh.getRow(i).getCell(14).toString(), sh.getRow(i).getCell(15).toString())); } } catch (Exception e) { e.printStackTrace(); } return conso; } public static SortedMap<Character, SortedSet<Consommable>> sortByInitials(List<Consommable> conso) { return conso.stream().collect(Collectors.groupingBy(consommable -> Character.toLowerCase(consommable.getDesignation().charAt(0)), TreeMap::new, Collectors.toCollection(TreeSet::new))); } }
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 020
7 juin 2018 à 14:05
7 juin 2018 à 14:05
Dans la mesure où ton code est dans le Java (et pas dans la JSP) tu peux faire un main() et tester en local, avec des println en plus si besoin. Tu peux aussi mettre des points de debug et faire du pas à pas.
public static void main(String[] args) { List<Consommable> list = readExcelStock(); System.out.println(list.size()); // 379 ? System.out.println(list); SortedMap<Character, SortedSet<Consommable>> map = sortByInitials(list); System.out.println(map.size()); // <= 26 System.out.println(map); }
TempsMort0
Messages postés
43
Date d'inscription
mardi 22 janvier 2013
Statut
Membre
Dernière intervention
1 août 2018
Modifié le 7 juin 2018 à 15:00
Modifié le 7 juin 2018 à 15:00
Yes, j'ai déjà rajouté ce main, enlevé le simple if, j'ai mis en place le try catch de votre message de ce matin :
Résultat pour la liste :
Résultat pour le SortedMap (normalement à la suite) :
Je ne comprends pas que faire quelque chose d'aussi simple soit si tricky, traiter du fichier .txt, .csv n'a rien de problématique... Je n'ai jamais pris autant de temps avec cette api Apache pour afficher des données en fonction d'un tri banal..
Résultat pour la liste :
Warning. Can't parse line 6. java.lang.NullPointerException
Warning. Can't parse line 387. java.lang.NullPointerException
//Pareil de 388 à 409...
Warning. Can't parse line 410. java.lang.NullPointerException
417
//Toutes les valeurs sous forme d'adresse
Résultat pour le SortedMap (normalement à la suite) :
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 0
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:44)
at java.base/java.lang.String.charAt(String.java:704)
at pac.cmd.CommandeStock.lambda$sortByInitials$0(CommandeStock.java:72)
at java.base/java.util.stream.Collectors.lambda$groupingBy$49(Collectors.java:1075)
at java.base/java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1494)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:511)
at pac.cmd.CommandeStock.sortByInitials(CommandeStock.java:72)
at pac.cmd.CommandeStock.main(CommandeStock.java:81)
Je ne comprends pas que faire quelque chose d'aussi simple soit si tricky, traiter du fichier .txt, .csv n'a rien de problématique... Je n'ai jamais pris autant de temps avec cette api Apache pour afficher des données en fonction d'un tri banal..
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 020
Modifié le 7 juin 2018 à 15:12
Modifié le 7 juin 2018 à 15:12
Donc le problème c'est le NullPointerException, une vraie erreur dont il va falloir regarder le détail (e.printStackTrace) car j'avais mis ce code là pour les IllegalArgumentException (des warning) que l'on aurait mis dans le constructeur mais ici c'est autre chose.
Evidemment il faudra regarder en parallèle de l'erreur à quoi correspondent dans le fichier Excel les lignes indiquées.
Evidemment il faudra regarder en parallèle de l'erreur à quoi correspondent dans le fichier Excel les lignes indiquées.
try { conso.add(...) } catch (Exception e) { System.err.println("Can't parse line " + i + " : "); e.printStackTrace(); }
TempsMort0
Messages postés
43
Date d'inscription
mardi 22 janvier 2013
Statut
Membre
Dernière intervention
1 août 2018
7 juin 2018 à 16:45
7 juin 2018 à 16:45
J'ai beau cherché toute l'après-midi, je tourne en rond..
J'ai printStackTrace :
J'ai 417 valeurs dans la List, les éléments s'affichent sous forme d'adresse car le toString est manquant mais ça ce n'est rien. Impossible de trouver comment régler ça..
J'ai printStackTrace :
java.lang.NullPointerException
at pac.cmd.CommandeStock.readExcelStock(CommandeStock.java:52)
at pac.cmd.CommandeStock.main(CommandeStock.java:77)
J'ai 417 valeurs dans la List, les éléments s'affichent sous forme d'adresse car le toString est manquant mais ça ce n'est rien. Impossible de trouver comment régler ça..
package pac.cmd; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import pac.bdd.beans.Consommable; import javax.servlet.http.HttpServletRequest; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.*; import java.util.stream.Collectors; public class CommandeStock implements Commande { private static final String STOCK_FILE_NAME = "C:\\Users\\lomoc\\Cours\\S4\\JSP\\webapps\\Actemium\\WEB-INF\\stock.xls"; private final String next; public CommandeStock(String next) { this.next = next; } public String execute(HttpServletRequest req) throws IOException, InvalidFormatException { List<Consommable> conso = readExcelStock(); req.setAttribute("conso", conso); req.setCharacterEncoding("UTF-8"); req.getServletContext().getRequestDispatcher("/WEB-INF/stock.jsp"); return next; } private static List<Consommable> readExcelStock() throws IOException, InvalidFormatException { List<Consommable> conso = new ArrayList<>(); try (FileInputStream fis = new FileInputStream(STOCK_FILE_NAME); Workbook wb = WorkbookFactory.create(fis)) { Sheet sh = wb.getSheet("STOCK"); int noOfRows = sh.getLastRowNum(); for (int i = 1; i < noOfRows; i++) { try { conso.add(new Consommable( sh.getRow(i).getCell(0).toString(), sh.getRow(i).getCell(1).toString(), sh.getRow(i).getCell(2).toString(), sh.getRow(i).getCell(3).toString(), sh.getRow(i).getCell(4).toString(), sh.getRow(i).getCell(5).toString(), sh.getRow(i).getCell(6).toString(), sh.getRow(i).getCell(0).toString(), sh.getRow(i).getCell(8).toString(), sh.getRow(i).getCell(9).toString(), sh.getRow(i).getCell(10).toString(), sh.getRow(i).getCell(11).toString(), sh.getRow(i).getCell(12).toString(), sh.getRow(i).getCell(13).toString(), sh.getRow(i).getCell(14).toString(), sh.getRow(i).getCell(15).toString())); } catch (NullPointerException e) { e.printStackTrace(); } } } return conso; } public static SortedMap<Character, SortedSet<Consommable>> sortByInitials(List<Consommable> conso) { return conso.stream().collect(Collectors.groupingBy(consommable -> Character.toLowerCase(consommable.getDesignation().charAt(0)), TreeMap::new, Collectors.toCollection(TreeSet::new))); } public static void main(String[] args) throws IOException, InvalidFormatException { List<Consommable> list = readExcelStock(); System.out.println(list.size()); // 379 ? System.out.println(list.toString()); SortedMap<Character, SortedSet<Consommable>> map = sortByInitials(list); System.out.println(map.size()); // <= 26 System.out.println(map); } }
KX
Messages postés
16753
Date d'inscription
samedi 31 mai 2008
Statut
Modérateur
Dernière intervention
25 novembre 2024
3 020
7 juin 2018 à 17:31
7 juin 2018 à 17:31
D'après la documentation, getCell(n) peut renvoyer null, ce qui explique que le toString plante.
https://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/Row.html#getCell-int-
Essayes ceci :
https://poi.apache.org/apidocs/dev/org/apache/poi/ss/usermodel/Row.html#getCell-int-
Essayes ceci :
public static String getCellAsString(Sheet sheet, int rownum, int cellnum) { Row row = sheet.getRow(rownum); if (row == null) { System.err.println("Warning: row undefined: " + rownum); return ""; } Cell cell = row.getCell(cellnum); if (cell == null) { System.err.println("Warning: on row " + rownum +" cell undefined: " + cellnum); return ""; } return cell.toString(); }
conso.add(new Consommable(getCellAsString(sh, i, 0), getCellAsString(sh, i, 1), getCellAsString(sh, i, 2), ...
6 juin 2018 à 09:49
Je ne comprends pas vraiment dans la méthode sortByInitials ce que symbolise la flèche ici :
C'est l'attribution à "consommable" qui est une valeur générique ?
Can only iterate over an array or an instance of java.lang.Iterable > Erreur tomcat
foreach not applicable to type 'java.util.SortedMap<java.lang.Character,java.util.SortedSet<pac.bdd.beans.Consommable>>' > Erreur IDE (Intellij)
L'import de la servlet :
Et oui les variables de ma classe Consommable sont comme précédemment que des String, j'arrangerais ça quand j'aurais plus de temps.
6 juin 2018 à 13:25
Je ne m'attendais pas vraiment à ce que tu la comprennes, l'important ici c'était surtout de te donner une idée de la signature de la méthode pour faire la correspondance avec son utilisation dans la JSP.
Mais si tu ne comprends pas ce mon code, il y a d'autres manière d'écrire cette méthode.
Pour comprendre : le premier paramètre de Collectors.groupingBy c'est une fonction qui permet de calculer la clé de la Map dans laquelle on va mettre l'objet. Ici c'est donc le calcul de l'initiale de sa désignation, sur le même principe que le que tu avais proposé.
"consommable", qui est avant la flèche, correspond au paramètre de la méthode. C'est pareil que faire :
Remarque : si tu écris la méthode à côté (conseillé), dans ce cas on pourrait faire une référence de méthode à la place de l'expression lambda.
En effet, j'en ai oublié une petite partie (je code de tête, sans tester...)
Comme pour les codes précédents, il faut utiliser la méthode entrySet() pour passer de la Map au Set<Entry>
6 juin 2018 à 14:59
ne marche pas, la List gêne, la méthode Entry attend que le 2ème élement ne soit pas une List mais un SortedSet :
Je ne sais pas si c'est la meilleure idée, je vais essayer de faire marcher ça.
6 juin 2018 à 15:23
Sauf que dans une première version du code j'avais Map<Character, List<Outil>> (qui perdait l'ordre) et quand j'ai changé le code Java j'ai oublié de changer le code de la JSP... (problèmes qui n'arriveraient pas avec la JSTL)
6 juin 2018 à 15:54
Soit cet import ne suffit pas :
Mais vu que j'appelle la méthode sortByInitials dans la JSP j'imagine que ce n'est pas le problème.
Soit la boucle est mauvaise mais il n'y a pas de raison :
ça doit être au remplissage que le problème réside :
Je pense déjà pouvoir mettre "List" dans la signature à la place de "Collection" mais ça n'arrangera pas le problème, mais après le doute s'installe.