私はList
のすべての要素を表示しようとしていますが、値ではなくObject
のポインタを表示しています。
これは私の印刷コードです...
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
それが要素の価値を印刷していない理由誰かが私を助けてもらえますか。
これはリストコンポーネントをプリントアウトすることに関するいくつかの例です:
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;
}
}
次のコードは簡潔で、コード例のループを回避します(そして、素敵なカンマを使用できます)。
System.out.println(Arrays.toString(list.toArray()));
しかし、他の人が指摘したように、リストの中のオブジェクトに対して実用的なtoString()メソッドが実装されていない場合は、注目しているオブジェクトポインタ(実際にはハッシュコード)が得られます。これは、リストに含まれているかどうかにかかわらず当てはまります。
Java 8以降、Listはデフォルトの "forEach"メソッドを継承し、これをメソッド参照 "System.out :: println"と組み合わせることができます。
list.forEach(System.out::println);
System.out.println(list);//toString() is easy and good enough for debugging.
toString()
of 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]
Java 8 Streamsアプローチ...
list.stream().forEach(System.out::println);
Screenに意味のある何かを出力するためには、リスト中のオブジェクトは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();
}
}
これが実行されると、screenに出力される結果は以下のとおりです。
t1 = Test$T1@19821f
t2 = 5
T1はtoStringメソッドをオーバーライドしないので、そのインスタンスt1はあまり有用ではないものとして出力されます。一方、T2はtoStringをオーバーライドするので、I/Oで使用されたときに表示される内容を制御します。画面上では、もう少し見やすくなります。
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);
}
}
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
)-コレクションの反復子が一般的に使用され、 fail-fast になるように設計されています。基になるコレクションが反復中に構造的に変更の場合、ConcurrentModificationException
をスローします。 ArrayList
の doc で述べたように:
構造変更は、1つ以上の要素を追加または削除する操作、またはバッキング配列を明示的にサイズ変更する操作です。単に要素の値を設定することは、構造的な変更ではありません。
したがって、ArrayList.forEach
の設定は問題なく許可されます。また、同時収集の場合にはConcurrentLinkedQueue
反復子は weakly-consistent になります。つまり、forEach
で渡されるアクションは、ConcurrentModificationException
exceptionをスローせずに構造的な変更も許可されます。 。ただし、ここでの変更は、その反復で表示される場合とされない場合があります。
2番目のアプローチ(Stream.forEach
)-順序は定義されていません。順次ストリームでは発生しない場合がありますが、仕様では保証されていません。また、アクションは本質的に干渉しないことが必要です。 doc で述べたように:
この操作の動作は明示的に非決定的です。並列ストリームパイプラインの場合、この操作はストリームの遭遇順序を尊重することを保証しません。そうすると、並列処理の利点が犠牲になります。
番目のアプローチ(Stream.forEachOrdered
)-アクションは、ストリームの遭遇順に実行されます。そのため、順序が重要なときはいつでもforEachOrdered
を気にせずに使用してください。 doc で述べたように:
ストリームに遭遇順序が定義されている場合、このストリームの各要素に対してストリームの遭遇順序でアクションを実行します。
同期コレクションを反復処理している間、最初のアプローチはコレクションのロックを1回取得し、アクションメソッドのすべての呼び出しでそれを保持しますが、ストリームの場合はコレクションのスプリッテレーターを使用します、ロックせず、すでに確立されている非干渉の規則に依存します。反復中にストリームをバッキングするコレクションが変更された場合、ConcurrentModificationException
がスローされるか、一貫性のない結果が発生する可能性があります。
4番目のアプローチ(Parallel Stream.forEach
)-既に述べたように、並列ストリームの場合に予想される遭遇順序を尊重する保証はありません。 forEachOrdered
には当てはまらない要素ごとに異なるスレッドでアクションが実行される可能性があります。
5番目のアプローチ(パラレルStream.forEachOrdered
)-forEachOrdered
は、ストリームがシーケンシャルかパラレルかに関係なく、ソースで指定された順序で要素を処理します。そのため、これを並列ストリームで使用する意味はありません。
あるいは、単にApache Commonsユーティリティを使用することもできます。
List<MyObject> myObjects = ...
System.out.println(ArrayUtils.toString(myObjects));
しかし、要素がオブジェクトであれば、Kshitij Mehtaが述べたように、そのオブジェクト内にメソッド "toString"を実装(オーバーライド)する必要があります(まだ実装されていない場合)。
class Person {
private String firstName;
private String lastName;
@Override
public String toString() {
return this.firstName + " " + this.lastName;
}
}
私は同様の問題に直面しました。私のコード:
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);
ToString()をオーバーライドしていない場合は、ダンプ関数を作成しました。これは基本的にオブジェクトのパブリックメンバーを出力するものです。ゲッターを呼び出すために簡単に拡張することができます。 Javadoc:
次の規則に従って、指定されたオブジェクトをSystem.outにダンプします。
- オブジェクトが反復可能な場合は、そのすべてのコンポーネントがダンプされます。
- Objectまたはそのスーパークラスの1つがtoString()をオーバーライドすると、 "toString"はダンプされます。
- そうでなければ、そのメソッドはオブジェクトのすべてのpublicメンバーに対して再帰的に呼び出される
/**
* 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();
}
私は今これに取り組んでいます...
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);
リストの内容を印刷するためのforループ
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
単一行で印刷したい場合(情報提供のみ):
String strList = String.join(", ", myList);
System.out.println("Elements : "+strList);
結果:
Elements : AA, BB
list.stream().map(x -> x.getName()).forEach(System.out::println);
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]
が表示されます。
文字列の配列リスト
list.forEach(s -> System.out.println(Arrays.toString((String[]) s )));
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()));
}
要素がprintendになるように、toString()メソッドをオーバーライドしてみてください。そのため、印刷方法は次のようになります。
for(int i=0;i<list.size();i++){
System.out.println(list.get(i).toString());
}