Задача состоит в следующем: на вход получаем строку с неким текстом, в этом тексте присутствуют метки (метка обозначается целым числовым значением окружённым фигурными скобками — {432}). Необходимо заменить эти метки на переданные аргументы (в качестве аргумента выступают разные типы данных). Также необходимо провести unit-тестирование с помощью JUnit 4.
Реализация форматирования строки
Для успешной реализации поставленной задачи необходимо создать три класса (три файла):
- Класс Main — основной класс нашей программы;
- Класс Formatter — класс, в котором описана логика замены меток на аргументы;
- Класс FormatterTest — класс unit-тестирования;
Класс Main
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public class Main { public static void main(String[] args) { Formatter exemplar = new Formatter( ); try { String instance = exemplar.build("Проект {0} поможет {1} освоить {2}", "NIKULUX", "тебе", "программирование"); System.out.println(instance); } catch (IndexOutOfBoundsException e) { } catch (NumberFormatException e) { } } } |
Класс Formatter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
import java.util.ArrayList; import java.util.Collections; public class Formatter { static String build(String formatString, Object... arguments) { if (formatString == null || formatString.equals("")) { return ""; } StringBuilder builder = new StringBuilder(formatString); ArrayList<Container> reverseContainer = parse(formatString, arguments); Collections.reverse(reverseContainer); for (Container element : reverseContainer) { element.formationMessageRow(builder); } return builder.toString( ); } static private ArrayList<Container> parse(String formatString, Object... arguments) { int indexOPenQuite = 0; int currentIndex = 0; boolean isReadArgument = false; ArrayList<Container> result = new ArrayList<Container>( ); StringBuilder argumentReader = new StringBuilder( ); for (char element : formatString.toCharArray( )) { currentIndex++; if (element == '{') { indexOPenQuite = currentIndex; isReadArgument = true; } else if (element == '}' && isReadArgument) { isReadArgument = false; String storageLabel = argumentReader.toString( ); try { int numberArgument = Integer.parseInt(storageLabel); result.add(new Container(indexOPenQuite, currentIndex, arguments[numberArgument])); } catch (IndexOutOfBoundsException e) { throw new IndexOutOfBoundsException("Number of argument our of range."); } catch (NumberFormatException e) { throw new IllegalArgumentException("Number of argument in bad format.", e); } argumentReader.delete(0, argumentReader.length( )); } else if (isReadArgument) { argumentReader.append(element); } } return result; } static class Container { private int indexOpenQuote; private int indexCloseQuote; private Object argument; Container(int open, int close, Object argument) { this.indexOpenQuote = open; this.indexCloseQuote = close; this.argument = argument; } public void formationMessageRow(StringBuilder builder) { try { builder.replace(this.indexOpenQuote - 1, this.indexCloseQuote, this.argument.toString( )); } catch (NullPointerException e) { } } } } |
Класс FormatterTest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
import static org.junit.Assert.*; public class FormatterTest { @org.junit.Test public void errorInput( ) throws Exception { try { Formatter errorInput = new Formatter( ); String value = errorInput.build("", "mom", "dad"); String expected = ""; assertEquals("Blank template without labels", expected, value); value = errorInput.build("here 0, here {1}, but {2}", "mom", "dad"); expected = "here 0, here dad, but {2}"; assertEquals("Instead of the 0 label, the digit 0", expected, value); value = errorInput.build("", ""); expected = ""; assertEquals("Passing an empty template", expected, value); value = errorInput.build(null, null); expected = ""; assertEquals("The pattern and the argument is null", expected, value); value = errorInput.build("Without parameters"); expected = "Without parameters"; assertEquals("Absence of the parameter", expected, value); } catch (NumberFormatException e) { } catch (IndexOutOfBoundsException e) { } } @org.junit.Test public void standardInput( ) throws Exception { try { Formatter standardInput = new Formatter( ); String value = standardInput.build("here {0} here {1}, but {2}", "mom", "dad", "I"); String expected = "here mom here dad, but I"; assertEquals("Correct writing and sending", expected, value); value = standardInput.build("Here come {3}, it's time for me to go through {1} of the country, visit {0} Museum and {2} km", 32, 196, 22, 777); expected = "Here come 777, it's time for me to go through 196 of the country, visit 32 Museum and 22 km"; assertEquals("Not consistent arrangement of labels in the template", expected, value); value = standardInput.build("Not {2} to take and {3} {0} {1}", "the lab", "Java", "so", "pass", "otherwise"); expected = "Not so to take and pass the lab Java"; assertEquals("Parameters more than labels", expected, value); value = standardInput.build("here {0} here {1}, but {2}", "mom", "dad"); expected = "here mom here dad, but {2}"; assertEquals("Parameters less than labels", expected, value); value = standardInput.build("here {0, here {1}, but {2}", "mom", "dad"); expected = "here {0, here {1}, but {2}"; assertEquals("Not a closed label", expected, value); } catch (NumberFormatException e) { } catch (IndexOutOfBoundsException e) { } } @org.junit.Test public void inputValuePrimitive( ) throws Exception { try { Formatter inputValuePrimitive = new Formatter( ); String value = inputValuePrimitive.build("Here int value {0}", 20543); String expected = "Here int value 20543"; assertEquals("Parameter of type int", expected, value); value = inputValuePrimitive.build("Here the float value is {0}", 0.68f); expected = "Here the float value is 0.68"; assertEquals("Parameter of type float", expected, value); value = inputValuePrimitive.build("Here the double value {0}", 3.14d); expected = "Here the double value 3.14"; assertEquals("Parameter of type double", expected, value); value = inputValuePrimitive.build("Here boolean value {0}", true); expected = "Here boolean value true"; assertEquals("Parameter of type boolean", expected, value); } catch (NumberFormatException e) { } catch (IndexOutOfBoundsException e) { } } @org.junit.Test public void inputValueReference( ) throws Exception { try { Formatter inputValueReference = new Formatter( ); String value = inputValueReference.build("Here the char value {0}", 'V'); String expected = "Here the char value V"; assertEquals("Parameter of type char", expected, value); Object objZero = "Object"; value = inputValueReference.build("Here object the value {0}", objZero); expected = "Here object the value Object"; assertEquals("Parameter of type Object with the number", expected, value); Object objOne = 1234.54; value = inputValueReference.build("Here object the value {0}", objOne); expected = "Here object the value 1234.54"; assertEquals("Parameter of type Object with the line", expected, value); String text = "text"; value = inputValueReference.build("Here the String value {0}", text); expected = "Here the String value text"; assertEquals("Parameter of type String", expected, value); Box box = new Box(111, 222, 333); value = inputValueReference.build("Parameter class: {0}", box); expected = "Parameter class: size 111 * 222 * 333"; assertEquals("The transfer of a class with three fields and an overload of toString", expected, value); } catch (IndexOutOfBoundsException e) { } catch (NumberFormatException e) { } } class Box { int width; int height; int depth; Box(int width, int height, int depth) { this.width = width; this.height = height; this.depth = depth; } @Override public String toString( ) { return "size " + width + " * " + height + " * " + depth; } } } |
Все тесты прошли успешно, если запустить Main, то результат будет следующим:
1 |
Проект NIKULUX поможет тебе освоить программирование |
Таким нехитрым образом мы разобрались с темой: «Форматирование строки, замена меток в шаблоне на свои значения — аргументы»!
1 thought on “Форматирование строки, замена меток в шаблоне на свои значения — аргументы”
Сергей
(20.07.2019 - 22:22)Не получилось с одним файлом.