Как центрировать строку, используя String.format? - PullRequest
13 голосов
/ 16 ноября 2011
public class Divers {
  public static void main(String args[]){

     String format = "|%1$-10s|%2$-10s|%3$-20s|\n";
     System.out.format(format, "FirstName", "Init.", "LastName");
     System.out.format(format, "Real", "", "Gagnon");
     System.out.format(format, "John", "D", "Doe");

     String ex[] = { "John", "F.", "Kennedy" };

     System.out.format(String.format(format, (Object[])ex));
  }
}

вывод:

|FirstName |Init.     |LastName            |
|Real      |          |Gagnon              |
|John      |D         |Doe                 |
|John      |F.        |Kennedy             |

Я хочу, чтобы вывод центрировался.Если я не использую флаг '-', выходные данные будут выровнены по правому краю.

Я не нашел флажок для центрирования текста в API.

Это статья содержит некоторую информацию о формате, но ничто в центре не оправдывает.

Ответы [ 6 ]

18 голосов
/ 16 ноября 2011

Я быстро взломал это.Теперь вы можете использовать StringUtils.center(String s, int size) в String.format.

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;

import org.junit.Test;

public class TestCenter {
    @Test
    public void centersString() {
        assertThat(StringUtils.center(null, 0), equalTo(null));
        assertThat(StringUtils.center("foo", 3), is("foo"));
        assertThat(StringUtils.center("foo", -1), is("foo"));
        assertThat(StringUtils.center("moon", 10), is("   moon   "));
        assertThat(StringUtils.center("phone", 14, '*'), is("****phone*****"));
        assertThat(StringUtils.center("India", 6, '-'), is("India-"));
        assertThat(StringUtils.center("Eclipse IDE", 21, '*'), is("*****Eclipse IDE*****"));
    }

    @Test
    public void worksWithFormat() {
        String format = "|%1$-10s|%2$-10s|%3$-20s|\n";
        assertThat(String.format(format, StringUtils.center("FirstName", 10), StringUtils.center("Init.", 10), StringUtils.center("LastName", 20)),
                is("|FirstName |  Init.   |      LastName      |\n"));
    }
}

class StringUtils {

    public static String center(String s, int size) {
        return center(s, size, ' ');
    }

    public static String center(String s, int size, char pad) {
        if (s == null || size <= s.length())
            return s;

        StringBuilder sb = new StringBuilder(size);
        for (int i = 0; i < (size - s.length()) / 2; i++) {
            sb.append(pad);
        }
        sb.append(s);
        while (sb.length() < size) {
            sb.append(pad);
        }
        return sb.toString();
    }
}
14 голосов
/ 23 августа 2012
public static String center(String text, int len){
    String out = String.format("%"+len+"s%s%"+len+"s", "",text,"");
    float mid = (out.length()/2);
    float start = mid - (len/2);
    float end = start + len; 
    return out.substring((int)start, (int)end);
}

public static void main(String[] args) throws Exception{
    // Test
    String s = "abcdefghijklmnopqrstuvwxyz";
    for (int i = 1; i < 200;i++){
        for (int j = 1; j < s.length();j++){
            center(s.substring(0, j),i);
        }
    }
}
7 голосов
/ 17 ноября 2011

Вот ответ, используя apache commons lang StringUtils.

Обратите внимание, что вам нужно добавить файл jar в путь сборки.Если вы используете maven, убедитесь, что в зависимостях добавлен общий язык lang.

import org.apache.commons.lang.StringUtils;
public class Divers {
  public static void main(String args[]){

    String format = "|%1$-10s|%2$-10s|%3$-20s|\n";
    System.out.format(format, "FirstName", "Init.", "LastName");
    System.out.format(format,StringUtils.center("Real",10),StringUtils.center("",10),StringUtils.center("Gagnon",20);

    System.out.format(String.format(format, (Object[])ex));
  }
}
5 голосов
/ 03 мая 2018

Преобразовал код, найденный в https://www.leveluplunch.com/java/examples/center-justify-string/, в удобную небольшую однострочную функцию:

public static String centerString (int width, String s) {
    return String.format("%-" + width  + "s", String.format("%" + (s.length() + (width - s.length()) / 2) + "s", s));
}

Использование:

public static void main(String[] args){
    String out = centerString(10, "afgb");
    System.out.println(out); //Prints "   afgb   "
}

Я думаю, что это очень аккуратнорешение, которое стоит упомянуть.

2 голосов
/ 29 октября 2017

Я поигрался с элегантным ответом Мертуареса выше и решил опубликовать свою версию.

public class CenterString {

    public static String center(String text, int len){
        if (len <= text.length())
            return text.substring(0, len);
        int before = (len - text.length())/2;
        if (before == 0)
            return String.format("%-" + len + "s", text);
        int rest = len - before;
        return String.format("%" + before + "s%-" + rest + "s", "", text);  
    }

    // Test
    public static void main(String[] args) {
        String s = "abcde";
        for (int i = 1; i < 10; i++){
            int max = Math.min(i,  s.length());
            for (int j = 1; j <= max; j++){
                System.out.println(center(s.substring(0, j), i) + "|");
            }
        }
    }
}

Вывод:

a|
a |
ab|
 a |
ab |
abc|
 a  |
 ab |
abc |
abcd|
  a  |
 ab  |
 abc |
abcd |
abcde|
  a   |
  ab  |
 abc  |
 abcd |
abcde |
   a   |
  ab   |
  abc  |
 abcd  |
 abcde |
   a    |
   ab   |
  abc   |
  abcd  |
 abcde  |
    a    |
   ab    |
   abc   |
  abcd   |
  abcde  | 

Практические отличия от кода Мертуареса:

  1. Шахта выполняет математику заранее и делает последнюю центрированную строку в одномвместо того, чтобы сделать слишком длинную строку, а затем взять из нее подстроку.Я предполагаю, что это немного более производительно, но я не проверял это.
  2. В случае текста, который не может быть идеально отцентрирован, мой последовательно помещает его на половину символа влево, а не на половинусимвол в правой половине времени.
  3. В случае текста, длина которого превышает указанную длину, моя всегда возвращает подстроку указанной длины, которая укоренена в начале исходного текста.
0 голосов
/ 30 августа 2016

Вот пример того, как я обработал центрирование заголовков столбцов в Java:

public class Test {
    public static void main(String[] args) {
        String[] months = { "January", "February", "March", "April", "May", "June", "July", "August", "September",
                "October", "November", "December" };

        // Find length of longest months value.
        int maxLengthMonth = 0;
        boolean firstValue = true;
        for (String month : months) {
            maxLengthMonth = (firstValue) ? month.length() : Math.max(maxLengthMonth, month.length());
            firstValue = false;
        }

        // Display months in column header row
        for (String month : months) {
            StringBuilder columnHeader = new StringBuilder(month);
            // Add space to front or back of columnHeader
            boolean addAtEnd = true;
            while (columnHeader.length() < maxLengthMonth) {
                if (addAtEnd) {
                    columnHeader.append(" ");
                    addAtEnd = false;
                } else {
                    columnHeader.insert(0, " ");
                    addAtEnd = true;
                }
            }
            // Display column header with two extra leading spaces for each
            // column
            String format = "  %" + Integer.toString(maxLengthMonth) + "s";
            System.out.printf(format, columnHeader);
        }
        System.out.println();

        // Display 10 rows of random numbers
        for (int i = 0; i < 10; i++) {
            for (String month : months) {
                double randomValue = Math.random() * 999999;
                String format = "  %" + Integer.toString(maxLengthMonth) + ".2f";
                System.out.printf(format, randomValue);
            }
            System.out.println();
        }
    }
}
...