Javaでリストのすべての要素を印刷する方法は?


236

のすべての要素を出力しようとしていますが、値ListではObjectなくのポインタを出力しています。

これは私の印刷コードです...

for(int i=0;i<list.size();i++){
    System.out.println(list.get(i));
} 

要素の値が出力されない理由を教えてください。


3
どのタイプであると宣言しListましたか?どのように宣言してインスタンス化したかを示してください。

toStringを呼び出す必要があり、クラスの説明を取得するか、リストに含まれる型のtoStringメソッドをオーバーライドします
L7ColWinters

それはあなたがそれを印刷するように言っていることです-あなたは別のtoStringまたは他の読みやすい文字列が必要です。
デイブニュートン

ArrayList <class> list = new ArrayList <class>();
user1335361 2012

4
同じことを行うために使用できるよりコンパクトな構文があることに注意してください for (Object obj : list) {System.out.println(obj);}
aroth

回答:


114

次に、リストコンポーネントを印刷する例をいくつか示します。

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;
    }
}

1
Modelクラスの紹介は質問にどのように関連していますか?
カールリヒター

4
リスト内のオブジェクトの種類がわからないため、これは単なる仮定です。
Crazenezz 2017年

477

次のコードはコンパクトで、コード例のループを回避します(また、優れたコンマを提供します)。

System.out.println(Arrays.toString(list.toArray()));

ただし、他の人が指摘したように、リスト内のオブジェクトに実装された賢明なtoString()メソッドがない場合は、観察しているオブジェクトポインター(実際にはハッシュコード)を取得します。これは、リストに含まれているかどうかにかかわらず当てはまります。


18
だけについてはどうですかlist.toString()
Jaskey 2014年

22
「list.toString()」を使用しても、通常の動作をオーバーライドするListインターフェースのカスタム実装(クラス名とハッシュコードを印刷するため)でない限り、個々の要素は印刷されません。
ホリーカミンズ

1
カスタムクラスを使用し、をオーバーライドしない場合toString、ソリューションはそのクラス名とハッシュコードも出力します。
Jaskey 2014

[value1、value2、value3]として出力されます。[]なしで印刷できますか?
デッドエンド'14

実際、@ Jaskeyは正しいです-彼らの答えはより良いものです。このArraysメソッドは配列には役立ちますが、のサブクラスには必要なくなりましたAbstractCollection
Holly Cummins

100

Java 8以降、Listはデフォルトの「forEach」メソッドを継承しており、これを次のようにメソッド参照「System.out :: println」と組み合わせることができます。

list.forEach(System.out::println);

2
@Katja Hahn、println出力に文字列を追加または追加することは可能ですか?
ガムキン

2
@gumkins、はい、できます。例:Arrays.stream(new String [] {"John"、 "Sansa"、 "Cersei"})。map(s-> "Hi" + s + "!")。forEach(System.out :: println) ;
Tiago Mussi

40
System.out.println(list);//toString() is easy and good enough for debugging.

toString()AbstractCollection それはそれを行うのに十分にクリーンで簡単になりますAbstractListサブクラスでAbstractCollectionそのループおよび不要でtoArray()のためにする必要が。

このコレクションの文字列表現を返します。文字列表現は、コレクションの要素のリストで構成され、イテレータによって返された順序で、角かっこ( "[]")で囲まれています。隣接する要素は、文字「、」(カンマとスペース)で区切られます。要素は、String.valueOf(Object)によって文字列に変換されます。

リストでカスタムオブジェクトを使用している場合、たとえばStudentを使用する場合は、そのオブジェクトをオーバーライドする必要があります。 toString())、意味のある出力を得るには、メソッド(常にこのメソッドをオーバーライドすること)。

以下の例を参照してください。

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;
    }
}

出力:

[string1, string2]
[student Tom age:15, student Kate age:16]

この答えは完全に正しいわけではないからです。それはそれを実現せずに多態性を使用しています。ここでの実際の継承階層ですlistList -> Collection -> Iterable -> Object。AbstractCollectionから実際に継承するクラスはArrayListです。したがって、この例でtoString()はが呼び出されると、ArrayListで定義されている実装を見つけAbstractCollectionます。以下のための継承階層注意ArrayListArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> Object
anon58192932

20

Java 8ストリームのアプローチ...

list.stream().forEach(System.out::println);

Katja Hahn'sと同じ回答
Karl Richter

いいえ、そうではありません。私はstream()を活用しています。
Bradley D

@BradleyDメソッド呼び出しの別のレイヤーをそこに追加することでどのような利点が実現しますか
Leon

15

リスト内のオブジェクトは、toString画面に意味のあるものを印刷するために実装されている必要があります。

違いを確認する簡単なテストを次に示します。

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();
    }
}

そして、これが実行されると、画面に出力される結果は次のとおりです。

t1 = Test$T1@19821f
t2 = 5

T1はtoStringメソッドをオーバーライドしないため、そのインスタンスt1はあまり役に立たないものとして出力されます。一方、T2はtoStringをオーバーライドするため、I / Oで使用されるときにT2が出力する内容を制御し、画面上で少し良いものを確認します。


11

Java 8の構成List<String> stringListを使用してさまざまな方法で印刷できるを検討してください。

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)

これらのアプローチはどのように互いに異なりますか?

最初のアプローチ(Iterable.forEach)- 通常、コレクションのイテレーターが使用されますが、これはフェイルファストになるように設計れています。つまり、反復中にConcurrentModificationException基になるコレクションが構造的に変更された場合にスローれます。のドキュメントで述べたようにArrayList

構造変更とは、1つ以上の要素を追加または削除する操作、またはバッキング配列を明示的にサイズ変更する操作です。単に要素の値を設定することは、構造的な変更ではありません。

したがってArrayList.forEach、値を設定することは問題なく許可されます。また、並行収集の場合、たとえばConcurrentLinkedQueueイテレータは一貫性弱いため、渡されたアクションはforEach構造変更さえも許可されません。ConcurrentModificationException例外をスローされます。ただし、ここでは、変更がその反復で表示される場合と表示されない場合があります。

2番目のアプローチ(Stream.forEach)- 順序は定義されていません。順次ストリームでは発生しない可能性がありますが、仕様では保証されていません。また、アクションは本来干渉しないことが必要です。ドキュメントで述べたように:

この操作の動作は明示的に非決定的です。並列ストリームパイプラインの場合、並列化の利点が失われるため、この操作はストリームの遭遇順序を尊重することを保証しません。

3番目のアプローチ(Stream.forEachOrdered)- アクションは、ストリームの遭遇順に実行されます。したがって、順序が重要な場合は常に、再考forEachOrderedせずに使用してください。ドキュメントで述べたように:

ストリームに定義された遭遇順序がある場合、ストリームの遭遇順序で、このストリームの各要素に対してアクションを実行します。

同期されたコレクションを反復する間、最初のアプローチはコレクションのロックを一度取得し、アクションメソッドへのすべての呼び出しで保持しますが、ストリームの場合、ロックを行わず、すでに確立されている非ルールに依存するコレクションのスプリッターを使用します-干渉。ストリームをバッキングするコレクションが反復処理中に変更された場合ConcurrentModificationException場合、スローされるか、一貫性のない結果が発生する可能性があります。

第4のアプローチ(並列Stream.forEach)- 既に述べたように、並列ストリームの場合に予期される遭遇順序を尊重する保証はありません。アクションが異なる要素に対して異なるスレッドで実行される可能性がありますforEachOrdered

第五のアプローチ(平行Stream.forEachOrdered) -forEachOrderedストリームが順次または平行であるか否かに関わらず、実際のソースで指定された順序で要素を処理します。したがって、これを並列ストリームで使用しても意味がありません。




7

同様の問題に直面しました。私のコード:

List<Integer> leaveDatesList = new ArrayList<>();

.....inserted value in list.......

方法1:forループでリストを印刷する

for(int i=0;i<leaveDatesList.size();i++){
    System.out.println(leaveDatesList.get(i));
}

方法2:リストをforEach、forループで出力する

for(Integer leave : leaveDatesList){
    System.out.println(leave);
}

方法3:Java 8でリストを印刷する

leaveDatesList.forEach(System.out::println);

5
  1. リストに含まれる要素の種類を指定していません。プリミティブデータ型の場合は、要素を出力できます。
  2. しかし、要素がオブジェクトの場合、Kshitij Mehtaが述べたように、「toString」メソッドをそのオブジェクト内に実装(オーバーライド)する必要があります(まだ実装されていない場合)。オブジェクト内から何か意味のあるものを返すようにする必要があります。例:

    class Person {
        private String firstName;
        private String lastName;
    
        @Override
        public String toString() {
            return this.firstName + " " + this.lastName;
        }
    }

3

System.out.println(list); 私のために働く。

ここに完全な例があります:

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);
     }
}

印刷されます[Hello, World]


他の以前の回答と違いはありません
カールリヒター

コピー、貼り付けが可能なインポート、クラス、メインメソッドの完全な例を示し、結果を示しました。したがって、私の意見ではそれを否決する理由はありません
jfmg 2017年


2

私はダンプ関数を書きました。これは、オブジェクトがtoString()をオーバーライドしていない場合、基本的にオブジェクトのパブリックメンバーを出力します。ゲッターを呼び出すように簡単に拡張できます。Javadoc:

次の規則を使用して、指定されたオブジェクトをSystem.outにダンプします。

  • オブジェクトが反復可能である場合、そのすべてのコンポーネントがダンプされます。
  • オブジェクトまたはそのスーパークラスの1つがtoString()をオーバーライドする場合、「toString」がダンプされます
  • そうでない場合、メソッドはオブジェクトのすべてのパブリックメンバーに対して再帰的に呼び出されます

/**
 * 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();
}

2

リストのコンテンツを出力するループ:

List<String> myList = new ArrayList<String>();
myList.add("AA");
myList.add("BB");

for ( String elem : myList ) {
  System.out.println("Element : "+elem);
}

結果:

Element : AA
Element : BB

情報を1行で印刷したい場合:

String strList = String.join(", ", myList);
System.out.println("Elements : "+strList);

結果:

Elements : AA, BB

1
    list.stream().map(x -> x.getName()).forEach(System.out::println);

どのようなタイプがxあり、OPの質問とどのように関連していますか?
カールリヒター

1

私はたまたまこれに取り組んでいます...

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);

1

これは、に格納されているオブジェクトのタイプList、およびtoString()メソッドの実装があるかどうかによって異なります。System.out.println(list)(すべての標準的なJavaオブジェクトの種類を印刷する必要がありStringLongIntegerなど)。カスタムオブジェクトタイプを使用している場合override toString()は、カスタムオブジェクトのメソッドを作成する必要があります。

例:

class Employee {
 private String name;
 private long id;

 @Override
 public String toString() {
   return "name: " + this.name() + 
           ", id: " + this.id();
 }  
}

テスト:

class TestPrintList {
   public static void main(String[] args) {
     Employee employee1 =new Employee("test1", 123);
     Employee employee2 =new Employee("test2", 453);
     List<Employee> employees = new ArrayList(2);
     employee.add(employee1);
     employee.add(employee2);
     System.out.println(employees);
   }
}

0
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()));
    }

0

要素がprintendになるようにtoString()メソッドをオーバーライドしようとします。したがって、印刷するメソッドは次のようになります。

for(int i=0;i<list.size();i++){
    System.out.println(list.get(i).toString());
} 

それがOPのコードが行うことです。への呼び出しtoStringは暗黙的です。
カールリヒター

-2
   List<String> textList=  messageList.stream()
                            .map(Message::getText)
                            .collect(Collectors.toList());

        textList.stream().forEach(System.out::println);
        public class Message  {

        String name;
        String text;

        public Message(String name, String text) {
            this.name = name;
            this.text = text;
        }

        public String getName() {
            return name;
        }

      public String getText() {
        return text;
     }
   }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.