J'essaie d'imprimer tous les éléments d'une List
, mais il affiche le pointeur de la Object
plutôt que la valeur.
Ceci est mon code d'impression ...
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
Quelqu'un pourrait-il m'aider s'il vous plaît, pourquoi ne pas afficher la valeur des éléments.
Voici quelques exemples sur la façon d’imprimer le composant de liste:
public class ListExample {
public static void main(String[] args) {
List<Model> models = new ArrayList<>();
// TODO: First create your model and add to models ArrayList, to prevent NullPointerException for trying this example
// Print the name from the list....
for(Model model : models) {
System.out.println(model.getName());
}
// Or like this...
for(int i = 0; i < models.size(); i++) {
System.out.println(models.get(i).getName());
}
}
}
class Model {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Ce qui suit est compact et évite la boucle dans votre exemple de code (et vous donne des virgules Nice):
System.out.println(Arrays.toString(list.toArray()));
Cependant, comme d'autres l'ont fait remarquer, si vous n'avez pas implémenté de méthodes sensibles toString () pour les objets de la liste, vous obtiendrez les pointeurs d'objet (codes de hachage, en fait) que vous observez. Cela est vrai qu'ils soient dans une liste ou non.
Depuis Java 8, List hérite d'une méthode par défaut "forEach" que vous pouvez combiner avec la référence de méthode "System.out :: println" comme ceci:
list.forEach(System.out::println);
System.out.println(list);//toString() is easy and good enough for debugging.
_ {toString()
of AbstractCollection
sera propre et assez facile à faire. AbstractList
est une sous-classe de AbstractCollection
, donc pas besoin de boucle, ni de toArray () nécessaire.
Retourne une représentation sous forme de chaîne de cette collection. La représentation sous forme de chaîne consiste en une liste des éléments de la collection dans le fichier ordre, ils sont retournés par son itérateur, entre crochets ("[]"). Les éléments adjacents sont séparés par les caractères "," (virgule Et espace). Les éléments sont convertis en chaînes comme par String.valueOf (Object).
Si vous utilisez un objet personnalisé dans votre liste, par exemple, Student, vous devez remplacer sa méthode toString()
(il est toujours bon de remplacer cette méthode) pour obtenir une sortie significative.
Voir l'exemple ci-dessous:
public class TestPrintElements {
public static void main(String[] args) {
//Element is String, Integer,or other primitive type
List<String> sList = new ArrayList<String>();
sList.add("string1");
sList.add("string2");
System.out.println(sList);
//Element is custom type
Student st1=new Student(15,"Tom");
Student st2=new Student(16,"Kate");
List<Student> stList=new ArrayList<Student>();
stList.add(st1);
stList.add(st2);
System.out.println(stList);
}
}
public class Student{
private int age;
private String name;
public Student(int age, String name){
this.age=age;
this.name=name;
}
@Override
public String toString(){
return "student "+name+", age:" +age;
}
}
sortie:
[string1, string2]
[student Tom age:15, student Kate age:16]
L'approche Java 8 Streams ...
list.stream().forEach(System.out::println);
La variable toString
doit être implémentée dans les objets de la liste pour qu'ils puissent imprimer quelque chose de significatif à l'écran.
Voici un test rapide pour voir les différences:
public class Test {
public class T1 {
public Integer x;
}
public class T2 {
public Integer x;
@Override
public String toString() {
return x.toString();
}
}
public void run() {
T1 t1 = new T1();
t1.x = 5;
System.out.println(t1);
T2 t2 = new T2();
t2.x = 5;
System.out.println(t2);
}
public static void main(String[] args) {
new Test().run();
}
}
Et quand ceci s’exécute, les résultats imprimés à l’écran sont:
t1 = Test$T1@19821f
t2 = 5
Etant donné que T1 ne remplace pas la méthode toString, son instance t1 s’affiche comme une tâche peu utile. D'autre part, T2 annulant toString, nous contrôlons ce qu'il imprime lorsqu'il est utilisé dans les E/S et nous voyons quelque chose d'un peu mieux à l'écran.
En utilisant les fonctionnalités de Java 8.
import Java.util.Arrays;
import Java.util.List;
/**
* @author AJMAL SHA
*
*/
public class ForEach {
public static void main(String[] args) {
List<String> features = Arrays.asList("Lambdas", "Default Method", "Stream API", "Date and Time API");
(features).forEach(System.out::println);
}
}
Considérez un List<String> stringList
qui peut être imprimé de différentes manières à l'aide des constructions Java 8:
stringList.forEach(System.out::println); // 1) Iterable.forEach
stringList.stream().forEach(System.out::println); // 2) Stream.forEach (order maintained generally but doc does not guarantee)
stringList.stream().forEachOrdered(System.out::println); // 3) Stream.forEachOrdered (order maintained always)
stringList.parallelStream().forEach(System.out::println); // 4) Parallel version of Stream.forEach (order not maintained)
stringList.parallelStream().forEachOrdered(System.out::println); // 5) Parallel version ofStream.forEachOrdered (order maintained always)
Première approche (Iterable.forEach
) - L'itérateur de la collection est généralement utilisé et est conçu pour être fail-fast ce qui signifie qu'il lancera ConcurrentModificationException
si la collection sous-jacente est structurellement modifié pendant l'itération. Comme mentionné dans le doc pour ArrayList
:
Une modification structurelle est toute opération qui ajoute ou supprime un ou plusieurs éléments, ou redimensionne explicitement le tableau de support; simplement mettre en place la valeur d'un élément n'est pas une modification structurelle.
Cela signifie donc que, pour ArrayList.forEach
, la valeur est autorisée sans problème. Et en cas de collecte simultanée, par ex. ConcurrentLinkedQueue
l'itérateur serait faiblement cohérent , ce qui signifie que les actions passées dans forEach
sont autorisées à effectuer des modifications structurelles même sans que ConcurrentModificationException
exception soit levé. Mais ici, les modifications pourraient ou non être visibles dans cette itération.
Deuxième approche (Stream.forEach
) - L'ordre n'est pas défini. Bien que cela ne se produise pas pour les flux séquentiels, la spécification ne le garantit pas. De plus, l'action doit être de nature non interférente. Comme mentionné dans doc :
Le comportement de cette opération est explicitement non déterministe. Pour conduites de flux parallèles, cette opération ne garantit pas à respecter l'ordre de rencontre du flux, car cela sacrifierait le bénéfice du parallélisme.
Troisième approche (Stream.forEachOrdered
) - L'action serait effectuée dans l'ordre de rencontre du flux. Donc, chaque fois que l'ordre est important, utilisez forEachOrdered
sans réfléchir. Comme mentionné dans le doc :
Effectue une action pour chaque élément de ce flux, dans la rencontre ordre du flux si le flux a un ordre de rencontre défini.
En itérant sur une collection synchronisée, l'approche first prend le verrou de la collection une fois et la conserve dans tous les appels à la méthode d'action, mais dans le cas de flux, elle utilise le séparateur de collection s'appuie sur les règles de non-ingérence déjà établies. Si la collecte de sauvegarde du flux est modifiée lors de l'itération, une variable ConcurrentModificationException
est générée ou un résultat incohérent peut survenir.
Quatrième approche (parallèle Stream.forEach
) - Comme mentionné précédemment, aucune garantie de respecter l'ordre de rencontre tel que prévu dans le cas de flux parallèles. Il est possible que l'action soit effectuée dans différents threads pour différents éléments, ce qui ne peut jamais être le cas avec forEachOrdered
.
Cinquième approche (Stream.forEachOrdered
parallèle) - La forEachOrdered
traitera les éléments dans l'ordre spécifié par la source, que le flux soit séquentiel ou parallèle. Cela n'a donc aucun sens de l'utiliser avec des flux parallèles.
Ou vous pouvez simplement utiliser les utilitaires Apache Commons:
List<MyObject> myObjects = ...
System.out.println(ArrayUtils.toString(myObjects));
Mais si les éléments sont des objets, comme l'a mentionné Kshitij Mehta, vous devez implémenter (remplacer) la méthode "toString" dans cet objet - si ce n'est déjà fait - et le laisser renvoyer quelque chose de complètement à l'intérieur de l'objet, exemple:
class Person {
private String firstName;
private String lastName;
@Override
public String toString() {
return this.firstName + " " + this.lastName;
}
}
J'ai rencontré des problèmes similaires. Mon code:
List<Integer> leaveDatesList = new ArrayList<>();
.....inserted value in list.......
Moyen 1: imprimer une liste dans une boucle for
for(int i=0;i<leaveDatesList.size();i++){
System.out.println(leaveDatesList.get(i));
}
Voie 2: imprimer la liste dans une boucle forEach, for for
for(Integer leave : leaveDatesList){
System.out.println(leave);
}
Méthode 3: impression de la liste en Java 8
leaveDatesList.forEach(System.out::println);
J'ai écrit une fonction de vidage, qui affiche essentiellement les membres publics d'un objet s'il n'a pas été remplacé par toString (). On pourrait facilement l'étendre pour appeler des Getters . Javadoc:
Vide un objet donné dans System.out, en appliquant les règles suivantes:
- Si l'objet est Iterable, tous ses composants sont vidés.
- Si l'Object ou l'une de ses superclasses écrase toString (), le "toString" est vidé
- Sinon, la méthode est appelée récursivement pour tous les membres publics de l'objet.
/**
* Dumps an given Object to System.out, using the following rules:<br>
* <ul>
* <li> If the Object is {@link Iterable}, all of its components are dumped.</li>
* <li> If the Object or one of its superclasses overrides {@link #toString()}, the "toString" is dumped</li>
* <li> Else the method is called recursively for all public members of the Object </li>
* </ul>
* @param input
* @throws Exception
*/
public static void dump(Object input) throws Exception{
dump(input, 0);
}
private static void dump(Object input, int depth) throws Exception{
if(input==null){
System.out.print("null\n"+indent(depth));
return;
}
Class<? extends Object> clazz = input.getClass();
System.out.print(clazz.getSimpleName()+" ");
if(input instanceof Iterable<?>){
for(Object o: ((Iterable<?>)input)){
System.out.print("\n"+indent(depth+1));
dump(o, depth+1);
}
}else if(clazz.getMethod("toString").getDeclaringClass().equals(Object.class)){
Field[] fields = clazz.getFields();
if(fields.length == 0){
System.out.print(input+"\n"+indent(depth));
}
System.out.print("\n"+indent(depth+1));
for(Field field: fields){
Object o = field.get(input);
String s = "|- "+field.getName()+": ";
System.out.print(s);
dump(o, depth+1);
}
}else{
System.out.print(input+"\n"+indent(depth));
}
}
private static String indent(int depth) {
StringBuilder sb = new StringBuilder();
for(int i=0; i<depth; i++)
sb.append(" ");
return sb.toString();
}
Je travaille sur cela maintenant ...
List<Integer> a = Arrays.asList(1, 2, 3);
List<Integer> b = Arrays.asList(3, 4);
List<int[]> pairs = a.stream()
.flatMap(x -> b.stream().map(y -> new int[]{x, y}))
.collect(Collectors.toList());
Consumer<int[]> pretty = xs -> System.out.printf("\n(%d,%d)", xs[0], xs[1]);
pairs.forEach(pretty);
list.stream().map(x -> x.getName()).forEach(System.out::println);
System.out.println(list);
travaille pour moi.
Voici un exemple complet:
import Java.util.List;
import Java.util.ArrayList;
public class HelloWorld {
public static void main(String[] args) {
final List<String> list = new ArrayList<>();
list.add("Hello");
list.add("World");
System.out.println(list);
}
}
Il imprimera [Hello, World]
.
Pour boucle pour imprimer le contenu d'une liste:
List<String> myList = new ArrayList<String>();
myList.add("AA");
myList.add("BB");
for ( String elem : myList ) {
System.out.println("Element : "+elem);
}
Résultat :
Element : AA
Element : BB
Si vous souhaitez imprimer sur une seule ligne (pour information uniquement):
String strList = String.join(", ", myList);
System.out.println("Elements : "+strList);
Résultat :
Elements : AA, BB
public static void main(String[] args) {
answer(10,60);
}
public static void answer(int m,int k){
AtomicInteger n = new AtomicInteger(m);
Stream<Integer> stream = Stream.generate(() -> n.incrementAndGet()).limit(k);
System.out.println(Arrays.toString(stream.toArray()));
}
essayez de remplacer la méthode toString () comme vous le souhaitez, l'élément sera printend. La méthode à imprimer peut être la suivante:
for(int i=0;i<list.size();i++){
System.out.println(list.get(i).toString());
}
Pour une liste de tableau de String
list.forEach(s -> System.out.println(Arrays.toString((String[]) s )));