Ответ 1
Вы можете преобразовать его в массив и затем распечатать с помощью Arrays.toString(Object[])
:
System.out.println(Arrays.toString(stack.toArray()));
Я хочу напечатать объект Stack<Integer>
так же хорошо, как и отладчик Eclipse (т.е. [1,2,3...]
), но печать его с помощью out = "output:" + stack
не возвращает этот приятный результат.
Просто, чтобы уточнить, я говорю о встроенной коллекции Java, поэтому я не могу переопределить ее toString()
.
Как я могу получить красивую версию стека для печати?
Вы можете преобразовать его в массив и затем распечатать с помощью Arrays.toString(Object[])
:
System.out.println(Arrays.toString(stack.toArray()));
String.join(",", yourIterable);
(Java 8)
Класс MapUtils, предлагаемый проектом Apache Commons, предлагает метод MapUtils.debugPrint
, который будет довольно печатать вашу карту.
С 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>
, а затем используем сборщик соединений для объединения каждого элемента в коллекции с ,
в качестве разделителя.
Внесите toString() в класс.
Я рекомендую Apache Commons ToStringBuilder, чтобы сделать это проще. При этом вам просто нужно написать такой метод:
public String toString() {
return new ToStringBuilder(this).
append("name", name).
append("age", age).
toString();
}
Чтобы получить этот вид вывода:
Person @7f54 [имя = Стивен, возраст = 29]
Существует также отражающая реализация.
System.out.println(коллекция c) уже распечатывает любой тип коллекции в удобочитаемом формате. Только если коллекция содержит определенные пользователем объекты, тогда вам нужно реализовать toString() в определенном пользователем классе для отображения содержимого.
Я согласен с приведенными выше замечаниями об переопределении 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();
}
}
Это не полномасштабная реализация, а просто стартер.
Гуава выглядит как хороший вариант:
Вы можете использовать класс "Объекты" из 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]
В Java8
//will prints each element line by line
stack.forEach(System.out::println);
или
//to print with commas
stack.forEach(
(ele) -> {
System.out.print(ele + ",");
}
);
С Apache Commons 3 вы хотите позвонить
StringUtils.join(myCollection, ",")
Просто изменил предыдущий пример для печати даже коллекции, содержащей объекты, определенные пользователем.
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));
}
}
в наши дни большинство коллекций имеют полезный 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 }}
}
}
Если это ваш собственный класс коллекции, а не встроенный, вам нужно переопределить его метод toString. Eclipse вызывает эту функцию для любых объектов, для которых у нее нет жесткого форматирования.
Будьте внимательны при вызове Sop on Collection, он может выбросить ConcurrentModification
Exception. Поскольку метод внутри toString
каждой коллекции внутренне вызывает Iterator
по коллекции.
Должен работать для любой коллекции, кроме 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();
}
Вы можете попробовать использовать
org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString(yourCollection);