How to center a string using String.format?

后端 未结 9 1589
陌清茗
陌清茗 2020-11-30 12:28
public class Divers {
  public static void main(String args[]){

     String format = \"|%1$-10s|%2$-10s|%3$-20s|\\n\";
     System.out.format(format, \"FirstName\",         


        
相关标签:
9条回答
  • 2020-11-30 12:44

    I was playing around with Mertuarez's elegant answer above and decided to post my version.

    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) + "|");
                }
            }
        }
    }
    

    Output:

    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  | 
    

    Practical differences from Mertuarez's code:

    1. Mine does the math up-front and makes the final centered string in one shot instead of making a too-long string and then taking a substring from it. I assume this is slightly more performant, but I did not test it.
    2. In the case of text that can't be perfectly centered, mine consistently puts it half a character to the left rather than putting it half a character to the right half of the time.
    3. In the case of text that's longer than the specified length, mine consistently returns a substring of the specified length that's rooted at the beginning of the original text.
    0 讨论(0)
  • 2020-11-30 12:54

    Converted the code found at https://www.leveluplunch.com/java/examples/center-justify-string/ into a handy, small one-line function:

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

    Usage:

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

    I think it's a very neat solution that's worth mentioning.

    0 讨论(0)
  • 2020-11-30 12:55

    Here's another example. Allows you to choose how you want to treat the center when there is a different number of padding characters added to the beginning and end of the string.

    Uses Java 11 String::repeat.

    public class Strings {
    
        public enum Lean {
            START,
            END
        }
    
        public static String center(String value, int targetLength, Lean lean) {
            return center(value, targetLength, lean, ' ');
        }
    
        private static String center(String value, int targetLength, Lean lean, char pad) {
    
            if (targetLength < 1) {
                throw new IllegalArgumentException("Cannot center something into less than one space.");
            }
    
            int sourceLength = value.length();
    
            if (sourceLength == targetLength) {
                return value;
            }
    
            int paddingToAdd = targetLength - sourceLength;
            int half = paddingToAdd / 2;
            String spad = Character.toString(pad);
            String padding = spad.repeat(half);
            String startExtra = "";
            String endExtra = "";
    
            if (paddingToAdd % 2 == 1) {
                if (lean == Lean.START) {
                    endExtra = spad;
                } else {
                    startExtra = spad;
                }
            }
    
            return padding + startExtra + value + endExtra + padding;
        }
    }
    
    
    
    public class StringsTest {
    
        @Test
        public void centerAbcIn9LeanStart() {
            doTest(
                    "abc",
                    9,
                    Strings.Lean.START,
                    "   abc   "
            );
        }
    
        @Test
        public void centerAbcIn9LeanEnd() {
            doTest(
                    "abc",
                    9,
                    Strings.Lean.END,
                    "   abc   "
            );
        }
    
        @Test
        public void centerAbcIn10LeanStart() {
            doTest(
                    "abc",
                    10,
                    Strings.Lean.START,
                    "   abc    "
            );
        }
    
        @Test
        public void centerAbcIn10LeanEnd() {
            doTest(
                    "abc",
                    10,
                    Strings.Lean.END,
                    "    abc   "
            );
        }
    
        @Test
        public void centerAbcdIn9LeanStart() {
            doTest(
                    "abcd",
                    9,
                    Strings.Lean.START,
                    "  abcd   "
            );
        }
    
        @Test
        public void centerAbcdIn9LeanEnd() {
            doTest(
                    "abcd",
                    9,
                    Strings.Lean.END,
                    "   abcd  "
            );
        }
    
        @Test
        public void centerAbcdIn10LeanStart() {
            doTest(
                    "abcd",
                    10,
                    Strings.Lean.START,
                    "   abcd   "
            );
        }
    
        @Test
        public void centerAbcdIn10LeanEnd() {
            doTest(
                    "abcd",
                    10,
                    Strings.Lean.START,
                    "   abcd   "
            );
        }
    
        @Test
        public void centerAIn1LeanStart() {
            doTest(
                    "a",
                    1,
                    Strings.Lean.START,
                    "a"
            );
        }
    
        @Test
        public void centerAIn1LeanEnd() {
            doTest(
                    "a",
                    1,
                    Strings.Lean.END,
                    "a"
            );
        }
    
        @Test
        public void centerAIn2LeanStart() {
            doTest(
                    "a",
                    2,
                    Strings.Lean.START,
                    "a "
            );
        }
    
        @Test
        public void centerAIn2LeanEnd() {
            doTest(
                    "a",
                    2,
                    Strings.Lean.END,
                    " a"
            );
        }
    
        @Test
        public void centerAIn3LeanStart() {
            doTest(
                    "a",
                    3,
                    Strings.Lean.START,
                    " a "
            );
        }
    
        @Test
        public void centerAIn3LeanEnd() {
            doTest(
                    "a",
                    3,
                    Strings.Lean.END,
                    " a "
            );
        }
    
        @Test
        public void centerAbIn3LeanStart() {
            doTest(
                    "ab",
                    3,
                    Strings.Lean.START,
                    "ab "
            );
        }
    
        @Test
        public void centerAbIn3LeanEnd() {
            doTest(
                    "ab",
                    3,
                    Strings.Lean.END,
                    " ab"
            );
        }
    
        public void doTest(String value, int targetLength, Strings.Lean lean, String expected) {
    
            assertThat(
                    "Test setup error: targetLength != expected.length()",
                    targetLength,
                    equalTo(expected.length()));
    
            assertThat(
                    "Test setup error: value != expected.trim()",
                    value,
                    equalTo(expected.trim()));
    
            String actual = Strings.center(value, targetLength, lean);
            assertThat(actual, equalTo(expected));
        }
    }
    
    0 讨论(0)
  • 2020-11-30 13:00

    This is another way to place a string in center.

    public static void center(String s, int length, CharSequence ch) {
        /* It works as follows
         * String centerString = String.format("|%" + (length - s.length()) + "s", s);
         * centerString = String.format("%" + -length + "s|", centerString);
         * System.out.println(centerString);
         */
    
        String centerString = String.format("%-" + length + "s|", String.format("|%" + (length - s.length()) + "s", s));
        System.out.println(centerString);
    }
    
    0 讨论(0)
  • 2020-11-30 13:02

    I quickly hacked this up. You can now use StringUtils.center(String s, int size) in 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();
        }
    }
    
    0 讨论(0)
  • 2020-11-30 13:02

    "one liner" since Java 9

        return n > s.length()
             ? " ".repeat((n - s.length()) / 2) + s + " ".repeat((n - s.length() + 1) / 2)
             : s;
    

    where:

    • " ".repeat(m) - fills the space.
    • n - s.length() - the diff size to fill.
    • diff / 2 - produces prefix size (e.g 5/2 = 2)
    • (diff + 1) / 2 - produces suffix size (e.g (5+1)/2 = 3)
    0 讨论(0)
提交回复
热议问题