のすべての要素を出力しようとしていますが、値List
ではObject
なくのポインタを出力しています。
これは私の印刷コードです...
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
要素の値が出力されない理由を教えてください。
for (Object obj : list) {System.out.println(obj);}
。
のすべての要素を出力しようとしていますが、値List
ではObject
なくのポインタを出力しています。
これは私の印刷コードです...
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
要素の値が出力されない理由を教えてください。
for (Object obj : list) {System.out.println(obj);}
。
回答:
次に、リストコンポーネントを印刷する例をいくつか示します。
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;
}
}
Model
クラスの紹介は質問にどのように関連していますか?
次のコードはコンパクトで、コード例のループを回避します(また、優れたコンマを提供します)。
System.out.println(Arrays.toString(list.toArray()));
ただし、他の人が指摘したように、リスト内のオブジェクトに実装された賢明なtoString()メソッドがない場合は、観察しているオブジェクトポインター(実際にはハッシュコード)を取得します。これは、リストに含まれているかどうかにかかわらず当てはまります。
list.toString()
。
toString
、ソリューションはそのクラス名とハッシュコードも出力します。
Arrays
メソッドは配列には役立ちますが、のサブクラスには必要なくなりましたAbstractCollection
。
Java 8以降、Listはデフォルトの「forEach」メソッドを継承しており、これを次のようにメソッド参照「System.out :: println」と組み合わせることができます。
list.forEach(System.out::println);
println
出力に文字列を追加または追加することは可能ですか?
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]
list
:List -> Collection -> Iterable -> Object
。AbstractCollectionから実際に継承するクラスはArrayList
です。したがって、この例でtoString()
はが呼び出されると、ArrayList
で定義されている実装を見つけAbstractCollection
ます。以下のための継承階層注意ArrayList
:ArrayList -> AbstractList -> AbstractCollection -> Collection -> Iterable -> Object
Java 8ストリームのアプローチ...
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で使用されるときにT2が出力する内容を制御し、画面上で少し良いものを確認します。
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
ストリームが順次または平行であるか否かに関わらず、実際のソースで指定された順序で要素を処理します。したがって、これを並列ストリームで使用しても意味がありません。
または、Apache Commonsユーティリティを使用することもできます。
List<MyObject> myObjects = ...
System.out.println(ArrayUtils.toString(myObjects));
使用String.join()
例:
System.out.print(String.join("\n", list)));
同様の問題に直面しました。私のコード:
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);
しかし、要素がオブジェクトの場合、Kshitij Mehtaが述べたように、「toString」メソッドをそのオブジェクト内に実装(オーバーライド)する必要があります(まだ実装されていない場合)。オブジェクト内から何か意味のあるものを返すようにする必要があります。例:
class Person {
private String firstName;
private String lastName;
@Override
public String toString() {
return this.firstName + " " + this.lastName;
}
}
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]
。
私はダンプ関数を書きました。これは、オブジェクトが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<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
私はたまたまこれに取り組んでいます...
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
、および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);
}
}
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());
}
toString
は暗黙的です。
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;
}
}
List
ましたか?どのように宣言してインスタンス化したかを示してください。