Tôi đang tìm một tiện ích sẽ in một Chuỗi hình chữ nhật [] [] vào một bảng có thể đọc được với độ dài cột chính xác.Mảng 2D in đẹp trong Java
Trả lời
Nếu bạn muốn một cái gì đó tương tự như MySQL đầu ra dòng lệnh của khách hàng, bạn có thể sử dụng một cái gì đó như thế:
import java.io.PrintStream;
import static java.lang.String.format;
import static java.lang.System.out;
public final class PrettyPrinter {
private static final char BORDER_KNOT = '+';
private static final char HORIZONTAL_BORDER = '-';
private static final char VERTICAL_BORDER = '|';
private static final String DEFAULT_AS_NULL = "(NULL)";
private final PrintStream out;
private final String asNull;
public PrettyPrinter(PrintStream out) {
this(out, DEFAULT_AS_NULL);
}
public PrettyPrinter(PrintStream out, String asNull) {
if (out == null) {
throw new IllegalArgumentException("No print stream provided");
}
if (asNull == null) {
throw new IllegalArgumentException("No NULL-value placeholder provided");
}
this.out = out;
this.asNull = asNull;
}
public void print(String[][] table) {
if (table == null) {
throw new IllegalArgumentException("No tabular data provided");
}
if (table.length == 0) {
return;
}
final int[] widths = new int[getMaxColumns(table)];
adjustColumnWidths(table, widths);
printPreparedTable(table, widths, getHorizontalBorder(widths));
}
private void printPreparedTable(String[][] table, int widths[], String horizontalBorder) {
final int lineLength = horizontalBorder.length();
out.println(horizontalBorder);
for (final String[] row : table) {
if (row != null) {
out.println(getRow(row, widths, lineLength));
out.println(horizontalBorder);
}
}
}
private String getRow(String[] row, int[] widths, int lineLength) {
final StringBuilder builder = new StringBuilder(lineLength).append(VERTICAL_BORDER);
final int maxWidths = widths.length;
for (int i = 0; i < maxWidths; i++) {
builder.append(padRight(getCellValue(safeGet(row, i, null)), widths[i])).append(VERTICAL_BORDER);
}
return builder.toString();
}
private String getHorizontalBorder(int[] widths) {
final StringBuilder builder = new StringBuilder(256);
builder.append(BORDER_KNOT);
for (final int w : widths) {
for (int i = 0; i < w; i++) {
builder.append(HORIZONTAL_BORDER);
}
builder.append(BORDER_KNOT);
}
return builder.toString();
}
private int getMaxColumns(String[][] rows) {
int max = 0;
for (final String[] row : rows) {
if (row != null && row.length > max) {
max = row.length;
}
}
return max;
}
private void adjustColumnWidths(String[][] rows, int[] widths) {
for (final String[] row : rows) {
if (row != null) {
for (int c = 0; c < widths.length; c++) {
final String cv = getCellValue(safeGet(row, c, asNull));
final int l = cv.length();
if (widths[c] < l) {
widths[c] = l;
}
}
}
}
}
private static String padRight(String s, int n) {
return format("%1$-" + n + "s", s);
}
private static String safeGet(String[] array, int index, String defaultValue) {
return index < array.length ? array[index] : defaultValue;
}
private String getCellValue(Object value) {
return value == null ? asNull : value.toString();
}
}
Và sử dụng nó như thế:
final PrettyPrinter printer = new PrettyPrinter(out);
printer.print(new String[][] {
new String[] {"FIRST NAME", "LAST NAME", "DATE OF BIRTH", "NOTES"},
new String[] {"Joe", "Smith", "November 2, 1972"},
null,
new String[] {"John", "Doe", "April 29, 1970", "Big Brother"},
new String[] {"Jack", null, null, "(yes, no last name)"},
});
Đoạn mã trên sẽ cho kết quả sau:
+----------+---------+----------------+-------------------+
|FIRST NAME|LAST NAME|DATE OF BIRTH |NOTES |
+----------+---------+----------------+-------------------+
|Joe |Smith |November 2, 1972|(NULL) |
+----------+---------+----------------+-------------------+
|John |Doe |April 29, 1970 |Big Brother |
+----------+---------+----------------+-------------------+
|Jack |(NULL) |(NULL) |(yes, no last name)|
+----------+---------+----------------+-------------------+
Bạn có thể thử
System.out.println(Arrays.deepToString(someRectangularStringArray));
Và đó là xinh đẹp như nó sẽ nhận được mà không cần mã cụ thể.
Đó không thực sự là bảng –
@DD. Tôi biết nó không phải là như là câu hỏi ban đầu là một chút ánh sáng về chi tiết tôi muốn chỉ ra điều này là (afaik) chỉ không có mã có thể giải pháp đủ tốt .... – fvu
Giải pháp tốt nhưng để có được điều này đẹp hơn tôi đã phải sử dụng thêm 'thay thế' trên kết quả như được khuyên [ở đây] (http://stackoverflow.com/questions/12845208#17423410). –
Tôi không biết về một thư viện util có thể làm điều này nhưng bạn có thể sử dụng hàm String.format để định dạng các chuỗi như bạn muốn hiển thị chúng. Đây là một ví dụ tôi nhanh chóng viết lên:
String[][] table = {{"Joe", "Bloggs", "18"},
{"Steve", "Jobs", "20"},
{"George", "Cloggs", "21"}};
for(int i=0; i<3; i++){
for(int j=0; j<3; j++){
System.out.print(String.format("%20s", table[i][j]));
}
System.out.println("");
}
này cung cấp cho các đầu ra sau đây:
Joe Bloggs 18
Steve Jobs 20
George Cloggs 21
Vì tôi stumbled khi tìm kiếm này cho một sẵn sàng để sử dụng máy in (nhưng không chỉ cho Strings) Tôi đã thay đổi Lyubomyr Shaydariv 's mã được viết cho the accepted answer một chút. Do đây có thể tăng giá trị cho các câu hỏi, tôi sẽ chia sẻ nó:
import static java.lang.String.format;
public final class PrettyPrinter {
private static final char BORDER_KNOT = '+';
private static final char HORIZONTAL_BORDER = '-';
private static final char VERTICAL_BORDER = '|';
private static final Printer<Object> DEFAULT = new Printer<Object>() {
@Override
public String print(Object obj) {
return obj.toString();
}
};
private static final String DEFAULT_AS_NULL = "(NULL)";
public static String print(Object[][] table) {
return print(table, DEFAULT);
}
public static <T> String print(T[][] table, Printer<T> printer) {
if (table == null) {
throw new IllegalArgumentException("No tabular data provided");
}
if (table.length == 0) {
return "";
}
if(printer == null) {
throw new IllegalArgumentException("No instance of Printer provided");
}
final int[] widths = new int[getMaxColumns(table)];
adjustColumnWidths(table, widths, printer);
return printPreparedTable(table, widths, getHorizontalBorder(widths), printer);
}
private static <T> String printPreparedTable(T[][] table, int widths[], String horizontalBorder, Printer<T> printer) {
final int lineLength = horizontalBorder.length();
StringBuilder sb = new StringBuilder();
sb.append(horizontalBorder);
sb.append('\n');
for (final T[] row : table) {
if (row != null) {
sb.append(getRow(row, widths, lineLength, printer));
sb.append('\n');
sb.append(horizontalBorder);
sb.append('\n');
}
}
return sb.toString();
}
private static <T> String getRow(T[] row, int[] widths, int lineLength, Printer<T> printer) {
final StringBuilder builder = new StringBuilder(lineLength).append(VERTICAL_BORDER);
final int maxWidths = widths.length;
for (int i = 0; i < maxWidths; i++) {
builder.append(padRight(getCellValue(safeGet(row, i, printer), printer), widths[i])).append(VERTICAL_BORDER);
}
return builder.toString();
}
private static String getHorizontalBorder(int[] widths) {
final StringBuilder builder = new StringBuilder(256);
builder.append(BORDER_KNOT);
for (final int w : widths) {
for (int i = 0; i < w; i++) {
builder.append(HORIZONTAL_BORDER);
}
builder.append(BORDER_KNOT);
}
return builder.toString();
}
private static int getMaxColumns(Object[][] rows) {
int max = 0;
for (final Object[] row : rows) {
if (row != null && row.length > max) {
max = row.length;
}
}
return max;
}
private static <T> void adjustColumnWidths(T[][] rows, int[] widths, Printer<T> printer) {
for (final T[] row : rows) {
if (row != null) {
for (int c = 0; c < widths.length; c++) {
final String cv = getCellValue(safeGet(row, c, printer), printer);
final int l = cv.length();
if (widths[c] < l) {
widths[c] = l;
}
}
}
}
}
private static <T> String padRight(String s, int n) {
return format("%1$-" + n + "s", s);
}
private static <T> T safeGet(T[] array, int index, Printer<T> printer) {
return index < array.length ? array[index] : null;
}
private static <T> String getCellValue(T value, Printer<T> printer) {
return value == null ? DEFAULT_AS_NULL : printer.print(value);
}
}
Và Printer.java:
public interface Printer<T> {
String print(T obj);
}
Cách sử dụng:
System.out.println(PrettyPrinter.print(some2dArray, new Printer<Integer>() {
@Override
public String print(Integer obj) {
return obj.toString();
}
}));
Tại sao sự thay đổi để T
? Vâng String
là không đủ, nhưng tôi không luôn luôn muốn cùng một đầu ra obj.toString()
đã cung cấp, vì vậy tôi sử dụng giao diện để có thể thay đổi theo ý muốn.
Thay đổi thứ hai không cung cấp lớp học với outstream
, tốt nếu bạn muốn sử dụng lớp với Trình ghi nhật ký như (Log4j // Logback), bạn chắc chắn sẽ gặp sự cố khi sử dụng luồng.
Tại sao thay đổi chỉ hỗ trợ cuộc gọi tĩnh? Tôi muốn sử dụng nó cho logger, và làm cho chỉ một cuộc gọi duy nhất dường như là sự lựa chọn hiển nhiên.
Xin chào. Cảm ơn bạn đã chỉ vào 'T' - tôi chỉ xem xét' Chuỗi '. Về phương thức tĩnh trả về một 'Chuỗi': Tôi muốn cung cấp một cú gọi ngược của nhà văn hoặc bắt chước một' PrintStream' để ghi vào một trình ghi, vì thường không cần thiết để có được kết quả của bản in đó, nhưng nó cần thiết để viết nó ở đâu đó mà không cần quan tâm đến việc ủy thác kết quả cho một đối tượng thích hợp có thể viết. –
Cũng lưu ý rằng 'Chuỗi' là một loại biểu diễn chung. 'T' không phải là và nó bao gồm một loại duy nhất cho một trường duy nhất, không phải là một bản ghi. Bởi vì bạn có thể muốn xử lý một danh sách các đối tượng trong đó mỗi trường có thể được chuyển đổi thành một 'Chuỗi'. Nếu bạn muốn in các hàng đẹp bao gồm một 'Danh sách
Tôi không đồng ý với nhận xét đầu tiên của bạn về PrintStream vì nó không tương thích với trình ghi nhật ký slf4j, nhưng đó có thể là một cuộc chiến thánh mà tôi không muốn tham gia (như phương pháp tĩnh được đề xuất). Để trả lời câu hỏi của bạn, đối với mỗi đối tượng bạn đưa vào giao diện Máy in của PrettyPrinter, bạn có thể định nghĩa bất kỳ chuyển đổi nào từ T thành String, kết thúc linh hoạt hơn rất nhiều so với bản gốc. Và bạn có thể lặp lại danh sách, nếu mọi trường đều giữ một danh sách của Person. Nếu bạn không chỉ định máy in T.toString() được gọi. –
JakWharton có một giải pháp tốt đẹp https://github.com/JakeWharton/flip-tables và định dạng Chuỗi [], Danh sách các đối tượng có phản ánh về tên thuộc tính và tập hợp kết quả. ví dụ.
List<Person> people = Arrays.asList(new Person("Foo", "Bar"), new Person("Kit", "Kat"));
System.out.println(FlipTableConverters.fromIterable(people, Person.class));
- 1. In danh sách 2D 2D đẹp
- 2. Lấy chiều dài mảng của một mảng 2D trong Java
- 3. In ấn 2D mảng trong định dạng ma trận
- 4. In các mảng trong Java
- 5. In đẹp ở Clojure
- 6. Câu hỏi về mảng 2D Java
- 7. Trình định dạng mã Java độc lập/làm đẹp/máy in đẹp?
- 8. Java - in mảng hai chiều
- 9. in đẹp vào một tệp trong ruby
- 10. boost :: property_tree XML in đẹp
- 11. Thư viện in đẹp nào?
- 12. Cách tốt nhất để in băm đẹp
- 13. NumPy: Dữ liệu dạng bảng in đẹp
- 14. 2d mảng số không
- 15. Chuyển tiếp mảng 2D
- 16. In đẹp trong vỏ MongoDB như mặc định
- 17. chuyển đổi mảng 2D thành mảng 2D thành
- 18. Scala - mảng in
- 19. Mảng 2d cắt thành các mảng 2d nhỏ hơn
- 20. Khởi tạo mảng 2D trong Python
- 21. Làm cách nào để in ra bản in đẹp trong Chrome DevTools Console?
- 22. Tháng Mảng trong JavaScript Không đẹp
- 23. Mảng 2D $ Chỉ mục trong AngularJS
- 24. Lọc các mảng 2D trong Excel VBA
- 25. in đẹp một thuật ngữ mở rộng
- 26. Cách lấy cột từ một mảng java 2D?
- 27. Khoảng cách in đẹp cho iOS
- 28. python - các thanh thông báo in đẹp
- 29. Mô-đun cho HTML in đẹp?
- 30. PHP "in đẹp" HTML (không gọn gàng)
Cảm ơn nhưng không làm việc có một dòng mới! – Hunsu
@ user230137 đúng, nhưng đây là cách đầu ra MySQL hoạt động. Nếu bạn thực hiện truy vấn 'SELECT', trong trình khách dòng lệnh gốc của MySQL, kết quả là các hàng có các ký tự dòng mới, thì đầu ra cũng bị hỏng, vì các ký tự đầu ra không được xử lý theo bất kỳ cách nào. Sự khác biệt duy nhất được biết với tôi là việc triển khai thực hiện của tôi nhỏ gọn hơn một chút, bởi vì nó không có ký tự đệm ngang 1 ký tự không gian, không giống như đầu ra dòng lệnh MySQL. –