のすべての要素を出力しようとしていますが、値ではなくList
ポインタを出力しています。Object
これは私の印刷コードです...
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
要素の値が出力されない理由を教えてください。
以下はコンパクトで、サンプルコードのループを回避します(そしてあなたに素敵なコンマを与えます):
System.out.println(Arrays.toString(list.toArray()));
ただし、他の人が指摘しているように、リスト内のオブジェクトに適切なtoString()メソッドを実装していない場合は、監視しているオブジェクトポインター(実際にはハッシュコード)を取得します。これは、リストに含まれているかどうかに関係なく当てはまります。
リストコンポーネントを印刷する方法の例を次に示します。
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;
}
}
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()
のAbstractCollection
は、それを行うのに十分クリーンで簡単になります。AbstractList
はのサブクラスでAbstractCollection
あるため、forループや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]
String.join()
たとえば、次のように使用します。
System.out.print(String.join("\n", list));
Java8Streamsアプローチ...
list.stream().forEach(System.out::println);
リスト内のオブジェクトは、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で使用されるときに印刷される内容を制御し、画面上で少し良いものが表示されます。
または、ApacheCommonsユーティリティを使用することもできます。
List<MyObject> myObjects = ...
System.out.println(ArrayUtils.toString(myObjects));
Java8コンストラクトList<String> stringList
を使用してさまざまな方法で印刷できるaを考えてみましょう。
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
、何も考えずに使用してください。ドキュメントに記載されているように:
ストリームにエンカウンター順序が定義されている場合は、ストリームのエンカウンター順序で、このストリームの各要素に対してアクションを実行します。
同期されたコレクションを反復処理する場合、最初のアプローチでは、コレクションのロックを1回取得し、すべての呼び出し呼び出しメソッドで保持しますが、ストリームの場合は、コレクションのスプリッターを使用します。これは、ロックせず、すでに確立されている非ルールに依存します。 -干渉。反復中にストリームをバッキングするコレクションが変更された場合、ConcurrentModificationException
がスローされるか、一貫性のない結果が発生する可能性があります。
4番目のアプローチ(並列Stream.forEach
)-
すでに述べたように、並列ストリームの場合に予想されるように遭遇順序を尊重する保証はありません。アクションが異なる要素に対して異なるスレッドで実行される可能性がありますが、これは。では決して当てはまりませんforEachOrdered
。
Stream.forEachOrdered
5番目のアプローチ(並列)-forEachOrdered
ストリームがシーケンシャルであるかパラレルであるかに関係なく、ソースによって指定された順序で要素を処理します。したがって、これを並列ストリームで使用することは意味がありません。
私も同様の問題に直面しました。私のコード:
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:Java8でリストを印刷する
leaveDatesList.forEach(System.out::println);
ただし、要素がオブジェクトの場合、Kshitij Mehtaが述べたように、そのオブジェクト内にメソッド「toString」を実装(オーバーライド)する必要があります(まだ実装されていない場合)。オブジェクト内から完全な意味を返すようにします。例:
class Person {
private String firstName;
private String lastName;
@Override
public String toString() {
return this.firstName + " " + this.lastName;
}
}
文字列の配列のリストについて
list.forEach(s -> System.out.println(Arrays.toString((String[]) s )));
リストの内容を出力する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
1行で印刷したい場合(参考までに):
String strList = String.join(", ", myList);
System.out.println("Elements : "+strList);
結果 :
Elements : AA, BB
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
の実装があるかどうかによって異なりますtoString()
。System.out.println(list)
すべての標準Javaオブジェクトタイプ(、など)を出力する必要がString
ありますLong
。Integer
カスタムオブジェクトタイプを使用している場合は、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);
}
}
list.stream().map(x -> x.getName()).forEach(System.out::println);
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();
}
私はたまたまこれに取り組んでいます...
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);
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());
}
Java11の問題の解決策は次のとおりです。
String separator = ", ";
String toPrint = list.stream().map(o -> String.valueOf(o)).collect(Collectors.joining(separator));
System.out.println(toPrint);
あなたが試すことができます:
2D(またはそれ以上)の場合
System.out.println(Arrays.deepToString(list.toArray()));
1D用
System.out.println(Arrays.toString(list.toArray()))
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;
}
}