Печать коллекций Java Nicely (toString не возвращает довольно вывод)

Я хочу напечатать объект Stack<Integer> так же хорошо, как и отладчик Eclipse (т.е. [1,2,3...]), но печать его с помощью out = "output:" + stack не возвращает этот приятный результат.

Просто, чтобы уточнить, я говорю о встроенной коллекции Java, поэтому я не могу переопределить ее toString().

Как я могу получить красивую версию стека для печати?

Ответ 1

Вы можете преобразовать его в массив и затем распечатать с помощью Arrays.toString(Object[]):

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

Ответ 2

String.join(",", yourIterable);

(Java 8)

Ответ 3

Класс MapUtils, предлагаемый проектом Apache Commons, предлагает метод MapUtils.debugPrint, который будет довольно печатать вашу карту.

Ответ 4

С java 8 потоками и сборщиками это можно сделать легко:

String format(Collection<?> c) {
  String s = c.stream().map(Object::toString).collect(Collectors.joining(","));
  return String.format("[%s]", s);
}

сначала мы используем map с Object::toString для создания Collection<String>, а затем используем сборщик соединений для объединения каждого элемента в коллекции с , в качестве разделителя.

Ответ 5

Внесите toString() в класс.

Я рекомендую Apache Commons ToStringBuilder, чтобы сделать это проще. При этом вам просто нужно написать такой метод:

public String toString() {
     return new ToStringBuilder(this).
       append("name", name).
       append("age", age).
       toString(); 
}

Чтобы получить этот вид вывода:

Person @7f54 [имя = Стивен, возраст = 29]

Существует также отражающая реализация.

Ответ 6

System.out.println(коллекция c) уже распечатывает любой тип коллекции в удобочитаемом формате. Только если коллекция содержит определенные пользователем объекты, тогда вам нужно реализовать toString() в определенном пользователем классе для отображения содержимого.

Ответ 7

Я согласен с приведенными выше замечаниями об переопределении toString() на ваших собственных классах (и об автоматизации этого процесса как можно больше).

Для классов, которые вы не указали, вы можете написать класс ToStringHelper с перегруженным методом для каждого класса библиотеки, который вы хотите обработать, на свой вкус:

public class ToStringHelper {
    //... instance configuration here (e.g. punctuation, etc.)
    public toString(List m) {
        // presentation of List content to your liking
    }
    public toString(Map m) {
        // presentation of Map content to your liking
    }
    public toString(Set m) {
        // presentation of Set content to your liking
    }
    //... etc.
}

EDIT: ответ на комментарий от xukxpvfzflbbld, здесь возможная реализация для упомянутых ранее случаев.

package com.so.demos;

import java.util.List;
import java.util.Map;
import java.util.Set;

public class ToStringHelper {

    private String separator;
    private String arrow;

    public ToStringHelper(String separator, String arrow) {
        this.separator = separator;
        this.arrow = arrow;
    }

   public String toString(List<?> l) {
        StringBuilder sb = new StringBuilder("(");
        String sep = "";
        for (Object object : l) {
            sb.append(sep).append(object.toString());
            sep = separator;
        }
        return sb.append(")").toString();
    }

    public String toString(Map<?,?> m) {
        StringBuilder sb = new StringBuilder("[");
        String sep = "";
        for (Object object : m.keySet()) {
            sb.append(sep)
              .append(object.toString())
              .append(arrow)
              .append(m.get(object).toString());
            sep = separator;
        }
        return sb.append("]").toString();
    }

    public String toString(Set<?> s) {
        StringBuilder sb = new StringBuilder("{");
        String sep = "";
        for (Object object : s) {
            sb.append(sep).append(object.toString());
            sep = separator;
        }
        return sb.append("}").toString();
    }

}

Это не полномасштабная реализация, а просто стартер.

Ответ 9

Вы можете использовать класс "Объекты" из JAVA (доступный с версии 1.7)

Collection<String> myCollection = Arrays.asList("1273","123","876","897");
Objects.toString(myCollection);

Выход: 1273, 123, 876, 897

Другая возможность заключается в использовании класса "MoreObjects" из Google Guave, который предоставляет множество полезных вспомогательных функций:

MoreObjects.toStringHelper(this).add("NameOfYourObject", myCollection).toString());

Вывод:   NameOfYourObject = [1273, 123, 876, 897]

Документы Guava

Ответ 10

В Java8

//will prints each element line by line
stack.forEach(System.out::println);

или

//to print with commas
stack.forEach(
    (ele) -> {
        System.out.print(ele + ",");
    }
);

Ответ 11

С Apache Commons 3 вы хотите позвонить

StringUtils.join(myCollection, ",")

Ответ 12

Просто изменил предыдущий пример для печати даже коллекции, содержащей объекты, определенные пользователем.

public class ToStringHelper {

    private  static String separator = "\n";

    public ToStringHelper(String seperator) {
        super();
        ToStringHelper.separator = seperator;

    }

    public  static String toString(List<?> l) {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (Object object : l) {
            String v = ToStringBuilder.reflectionToString(object);
            int start = v.indexOf("[");
            int end = v.indexOf("]");
            String st =  v.substring(start,end+1);
            sb.append(sep).append(st);
            sep = separator;
        }
        return sb.toString();
    }

    public static String toString(Map<?,?> m) {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (Object object : m.keySet()) {
            String v = ToStringBuilder.reflectionToString(m.get(object));
            int start = v.indexOf("[");
            int end = v.indexOf("]");
            String st =  v.substring(start,end+1);
            sb.append(sep).append(st);
            sep = separator;
        }
        return sb.toString();
    }

    public static String toString(Set<?> s) {
        StringBuilder sb = new StringBuilder();
        String sep = "";
        for (Object object : s) {
            String v = ToStringBuilder.reflectionToString(object);
            int start = v.indexOf("[");
            int end = v.indexOf("]");
            String st =  v.substring(start,end+1);
            sb.append(sep).append(st);
            sep = separator;
        }
        return sb.toString();
    }

    public static void print(List<?> l) {
        System.out.println(toString(l));    
    }
    public static void print(Map<?,?> m) {
        System.out.println(toString(m));    
    }
    public static void print(Set<?> s) {
        System.out.println(toString(s));    
    }

}

Ответ 13

в наши дни большинство коллекций имеют полезный toString() в Java (Java7/8). Поэтому нет необходимости выполнять потоковые операции для объединения того, что вам нужно, просто переопределите toString вашего класса значений в коллекции, и вы получите то, что вам нужно.

AbstractMap и AbstractCollection реализуют toString(), вызывая toString для каждого элемента.

ниже показан тестовый класс для демонстрации поведения.

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;

public class ToString {
  static class Foo {
    int i;
    public Foo(int i) { this.i=i; }
    @Override
    public String toString() {
        return "{ i: " + i + " }";
    }
  }
  public static void main(String[] args) {
    List<Foo> foo = new ArrayList<>();
    foo.add(new Foo(10));
    foo.add(new Foo(12));
    foo.add(new Foo(13));
    foo.add(new Foo(14));
    System.out.println(foo.toString());
    // prints: [{ i: 10 }, { i: 12 }, { i: 13 }, { i: 14 }]

    Map<Integer, Foo> foo2 = new HashMap<>();
    foo2.put(10, new Foo(10));
    foo2.put(12, new Foo(12));
    foo2.put(13, new Foo(13));
    foo2.put(14, new Foo(14));
    System.out.println(foo2.toString());
    // prints: {10={ i: 10 }, 12={ i: 12 }, 13={ i: 13 }, 14={ i: 14 }}
  }
}

Ответ 14

Если это ваш собственный класс коллекции, а не встроенный, вам нужно переопределить его метод toString. Eclipse вызывает эту функцию для любых объектов, для которых у нее нет жесткого форматирования.

Ответ 15

Будьте внимательны при вызове Sop on Collection, он может выбросить ConcurrentModification Exception. Поскольку метод внутри toString каждой коллекции внутренне вызывает Iterator по коллекции.

Ответ 16

Должен работать для любой коллекции, кроме Map, но ее легко поддерживать. Измените код, чтобы передать эти 3 символа в случае необходимости.

static <T> String seqToString(Iterable<T> items) {
    StringBuilder sb = new StringBuilder();
    sb.append('[');
    boolean needSeparator = false;
    for (T x : items) {
        if (needSeparator)
            sb.append(' ');
        sb.append(x.toString());
        needSeparator = true;
    }
    sb.append(']');
    return sb.toString();
}

Ответ 17

Вы можете попробовать использовать

org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString(yourCollection);