windu.2b Posté(e) le 5 septembre 2007 Partager Posté(e) le 5 septembre 2007 Bonjour, J'aimerais faire une classe héritant d'ArrayList pour y stocker des valeurs de type int, float, double... afin de pouvoir faire des sum(), average(), très facilement. Je veux donc me baser sur la généricité de Java 5, afin de ne pas tenir compte du type exact (Integer, Float, Double...) mais j'ai des problèmes! Voilà ce que j'ai déjà fait: /** * MathList.java 5 sept. 07 windu.2b */ import java.util.*; /** * @author windu.2b * */ public class MathList<Number> extends ArrayList { /** * */ private static final long serialVersionUID = 6905001321588101837L; @SuppressWarnings("unchecked") public MathList( String s ) { StringTokenizer st = new StringTokenizer( s ); while ( st.hasMoreTokens() ) { add( ( Number ) st.nextToken() ); } } public Number sum() { Number sum; for( Object o : toArray() ) { // que faire? } return sum; } } Le constructeur est prévu pour pouvoir recevoir une chaîne de valeurs séparées par des ';' (c'est spécifique à mon utilisation). Là où cela coince, c'est dans la boucle for: je ne sais pas comment ajouter les valeurs Si quelqu'un a une idée, ou une autre solution à me proposer Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 5 septembre 2007 Partager Posté(e) le 5 septembre 2007 Deux problèmes dans ta classe : 1. Caster sauvagement une String (renvoyée par st.nextToken()) en Number me paraît pour le moins dangereux 2. C'est bien beau d'avoir un ensemble de Numbers, mais on ne peut effectuer aucune opération dessus. Il faudrait d'abord les transformer en int, double... (avec intValue(), doubleValue, etc.), mais comme tu ne connais pas d'avance ton type... Il faudrait que tu reformules ton besoin en termes fonctionnels, et on verra si on peut trouver une solution technique acceptable. Lien vers le commentaire Partager sur d’autres sites More sharing options...
PiFou86 Posté(e) le 6 septembre 2007 Partager Posté(e) le 6 septembre 2007 Tu devrais peut-être plutot passer par du polymorphisme que par de la généricité. Mais la encore, tu auras des problèmes de types... Pour ce genre de truc, je te conseille d'autres language si tu peux en changer (python, ocaml, c++) Lien vers le commentaire Partager sur d’autres sites More sharing options...
windu.2b Posté(e) le 6 septembre 2007 Auteur Partager Posté(e) le 6 septembre 2007 Merci pour vos réponses! Tout débord oui le cast est sans doute un peu bourrin, je reverrai ça... Ensuite, non je ne peux pas changer de langages. Ensuite, je ne suis pas sûr d'avoir bien compris ce passage: Il faudrait que tu reformules ton besoin en termes fonctionnels, et on verra si on peut trouver une solution technique acceptable. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 6 septembre 2007 Partager Posté(e) le 6 septembre 2007 Hé bien, plutôt que de nous dire : je veux absolument utiliser une ArrayList générique qui prend une String en param, dis-nous plutôt quel est ton besoin exact en termes fonctionnels (ex: effectuer des opérations sur un ensemble de valeurs de type entier). Si ça se trouve, la solution optimale n'utilise pas du tout les génériques, voire même pas les collections... Lien vers le commentaire Partager sur d’autres sites More sharing options...
windu.2b Posté(e) le 6 septembre 2007 Auteur Partager Posté(e) le 6 septembre 2007 Ah oki... désolé Donc je dois récupérer des données contenues dans une BDD, et certaines de ces données sont stockées ainsi: 1;2;3;4:5;6;7;8;9;10 Sauf que parfois ce sont des float et non des entiers (je sais quelles cases de la table contiennent des int et lesquelles contiennent des float, donc le pb n'est pas trop à ce niveau là). Ce que je compte faire, c'est récupérer cette valeur, la "casser" pour en extraire les valeurs, et stocker le tout sous une *List ou une Collection. Je comptais ensuite créer une classe héritant de *List (ou Collection) afin de faciliter tout ça, et surtout me permettre les calculs dont j'ai besoin (sommes et moyennes principalement) sur toutes ces valeurs. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 7 septembre 2007 Partager Posté(e) le 7 septembre 2007 Hummm je t'ai bricolé ça, dis-moi si ça te convient ? import java.util.ArrayList; import java.util.Iterator; public class GenericMathList<E extends Number> extends ArrayList<Number> { private static final long serialVersionUID = -7103399393697283325L; // ====================================================================== // Parseurs de listes de valeurs // ====================================================================== public void parseInts(String intList) { String[] ints = intList.split(";"); for(String s:ints) { add(new Integer(s)); } } public void parseFloats(String floatList) { String[] ints = floatList.split(";"); for(String s:ints) { add(new Float(s)); } } // ====================================================================== // Méthodes mathématiques // ====================================================================== public int intSum() { int sum = 0; for(Iterator<Number> it=iterator(); it.hasNext() { sum += it.next().intValue(); } return sum; } public float floatSum() { float sum = 0.0F; for(Iterator<Number> it=iterator(); it.hasNext() { sum += it.next().floatValue(); } return sum; } public float intAvg() { return intSum()/size(); } public float floatAvg() { return floatSum()/size(); } // ====================================================================== // Exemple d'utilisation // ====================================================================== public static void main(String[] args) { // Opérations sur les floats String floats = "1.1;2.1;3.1;4.1"; GenericMathList<Float> gmlf = new GenericMathList<Float>(); gmlf.parseFloats(floats); System.out.printf("%25s %-6d%n", "Int sum of float list :", gmlf.intSum()); System.out.printf("%25s %-6.2f%n", "Float sum of float list :", gmlf.floatSum()); // Opérations sur les Ints String ints = "1;8;2;4;6"; GenericMathList<Integer> gmli = new GenericMathList<Integer>(); gmli.parseFloats(ints); System.out.printf("%25s %-6d%n", "Int sum of int list :", gmli.intSum()); System.out.printf("%25s %-6.2f%n", "Float sum of int list :", gmli.floatSum()); } } Lien vers le commentaire Partager sur d’autres sites More sharing options...
windu.2b Posté(e) le 7 septembre 2007 Auteur Partager Posté(e) le 7 septembre 2007 Merci bien, la réponse me convient même si elle n'est pas exactement ce que j'aurais espéré (la généricité a disparu, mais si on ne peut pas faire autrement...) Bon, je marque ça en [Résolu] quand même Lien vers le commentaire Partager sur d’autres sites More sharing options...
lorinc Posté(e) le 7 septembre 2007 Partager Posté(e) le 7 septembre 2007 en fait, tu voudrais une méthode sum() qui te pond la bonne somme peut importe ce que tu mets dedans, c'est ça ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
PiFou86 Posté(e) le 8 septembre 2007 Partager Posté(e) le 8 septembre 2007 Pour les fonctions sum tu peux tjs faire des fonctions static... import java.util.*; public class MathList<T extends Number> extends Vector<Number> { /** * */ private static final long serialVersionUID = 6905001321588101837L; public MathList(String s, Class c) { if (c == Integer.class) parseInts(s); if (c == Float.class) parseFloats(s); } public void parseInts(String intList) { String[] ints = intList.split(";"); for(String s:ints) { add(new Integer(s)); } } public void parseFloats(String floatList) { String[] ints = floatList.split(";"); for(String s:ints) { add(new Float(s)); } } static public Integer sum(MathList<Integer> l) { int res = 0; for (Object e : l) res += ((Integer)e).intValue(); return new Integer(res); } static public Float sum(MathList<Float> l) { float res = 0.0f; for (Object e : l) res += ((Float)e).floatValue(); return new Float(res); } static public void main(String args[]) { MathList<Integer> l1 = new MathList<Integer>("1;2;3", Integer.class); MathList<Float> l2 = new MathList<Float>("1.5;2.;3.3", Float.class); System.out.println("sum 1 : " + MathList.sum(l1)); System.out.println("sum 2 : " + MathList.sum(l2)); } } Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 8 septembre 2007 Partager Posté(e) le 8 septembre 2007 Hummm, je ne vois pas bien l'intérêt des modifications apportées par PiFou86 ? - Pourquoi hériter de Vector qui est inutilement synchronisé ? - Pourquoi utiliser des méthodes statiques puisque de toute façon on est obligé d'instancier une MathList ? - En déclarant un constructeur à arguments et en forçant son utilisation, le programmeur ne peut plus utiliser les autres constructeurs d'ArrayList - Ses méthodes sum() forcent l'utilisation de MathList<Float> ou <Integer>. Et si l'utilisateur avait déjà placé d'autres Numbers (Double, par exemple) dans la liste et voulait effectuer des calculs avec ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
Sentinel Posté(e) le 8 septembre 2007 Partager Posté(e) le 8 septembre 2007 Enfin si tu veux vraiment considérer la classe comme une classe utilitaire externe à ta liste, tu peux faire comme ça : import java.util.ArrayList; import java.util.List; public class MathListUtils { // ====================================================================== // Parseurs de listes de valeurs // ====================================================================== // Note : utilisable avec List<Number> et <Integer> public static void addInts(List<? super Integer> list, String intList) { String[] ints = intList.split(";"); for(String s:ints) { list.add(new Integer(s)); } } // Note : utilisable avec List<Number> et <Float> public static void addFloats(List<? super Float> list, String floatList) { String[] floats = floatList.split(";"); for(String s:floats) { list.add(new Float(s)); } } // ====================================================================== // Méthodes mathématiques // ====================================================================== // Note : utilisable avec List<Number> et et <Integer> et <Float> public static int intSum(List<? extends Number> list) { int sum = 0; for(Number n:list) { sum += n.intValue(); } return sum; } // Note : utilisable avec List<Number> et et <Integer> et <Float> public static float floatSum(List<? extends Number> list) { float sum = 0.0F; for(Number n:list) { sum += n.floatValue(); } return sum; } // Note : utilisable avec List<Number> et et <Integer> et <Float> public float intAvg(List<? extends Number> list) { return MathListUtils.intSum(list)/list.size(); } // Note : utilisable avec List<Number> et et <Integer> et <Float> public float floatAvg(List<? extends Number> list) { return MathListUtils.floatSum(list)/list.size(); } // ====================================================================== // Exemple d'utilisation // ====================================================================== public static void main(String[] args) { // Opérations sur les floats List<Number> floatNumbers = new ArrayList<Number>(); MathListUtils.addFloats(floatNumbers, "1.1;2.1;3.1;4.1"); System.out.printf("%25s %-6d%n", "Int sum of float list :", MathListUtils.intSum(floatNumbers)); System.out.printf("%25s %-6.2f%n", "Float sum of float list :", MathListUtils.floatSum(floatNumbers)); // Opérations sur les floats List<Number> intNumbers = new ArrayList<Number>(); MathListUtils.addInts(intNumbers, "1;2;10;4;8"); System.out.printf("%25s %-6d%n", "Int sum of float list :", MathListUtils.intSum(intNumbers)); System.out.printf("%25s %-6.2f%n", "Float sum of float list :", MathListUtils.floatSum(intNumbers)); } } Lien vers le commentaire Partager sur d’autres sites More sharing options...
PiFou86 Posté(e) le 8 septembre 2007 Partager Posté(e) le 8 septembre 2007 Le paramètre dans le constructeur c'est simplement pour connaitre le type dans le constructeur. Le problème de faire des intSum et floatSum, c'est que tu dois faire des floatSum ou intSum... ce qui peut être chiant si tu veux être générique. Donc comme tu dis dans ton exemple, si le programmeur veut permettre d'autres types, il suffit d'écrire les autres méthodes, c'est rapide et homogène. Après c'est une question de gout. Pour le vector ou l'arraylist, il n'y a pas de rapport, je voulais seulement un container :) Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.