Лучший способ построить строку, избегая повторения
У меня есть жестко закодированная строка, которая будет использоваться в URL, и я хочу знать, каков наилучший способ создать эту строку без необходимости повторять слова country, or, and, number
? Это сокращенная версия, поскольку в URL добавлено больше стран и номеров.
String url = "&filter=country='UK' or "
+ "country='FR' or "
+ "country='CA' or "
+ "country='US' and "
+ "number='123' and "
+ "number='789'";
3 ответа
Решение
Вы можете использовать комбинацию StringBuilder
а также String
форматы для создания вашей конкретной параметризации URL.
Вот пример:
// test data
List<String> countries = Arrays.asList("UK", "FR","CA", "US");
List<String> numbers = Arrays.asList("123", "789");
// these can be compile-time constants
String disjunct = " or ";
String conjunct = " and ";
String countryFormat = "country='%s'";
String numberFormat = "number='%s'";
// result
StringBuilder result = new StringBuilder("&filter=");
// adding countries
for (String country: countries) {
result.append(String.format(countryFormat, country)).append(disjunct);
}
// removing last "or"
result.delete(result.lastIndexOf(disjunct), result.length());
// adding first "and"
result.append(conjunct);
// adding numbers
for (String number: numbers) {
result.append(String.format(numberFormat, number)).append(conjunct);
}
// removing last "and"
result.delete(result.lastIndexOf(conjunct), result.length());
// printing result
System.out.println(result);
Выход
&filter=country='UK' or country='FR' or country='CA' or country='US' and number='123' and number='789'
Я предлагаю вам создать массивы для хранения каждого различия и добавить их в цикл for:
String[] countries = {"'UK' or ", "'FR' or ", "'CA' or ", "'US' and "};
String[] numbers = {"'123' and ", "'789'"};
StringBuilder sb = new StringBuilder("&filter=");
for (String country : countries) {
sb.append("country=").append(country);
}
for (String number : numbers) {
sb.append("number=").append(number);
}
String url = sb.toString();
Вы также можете создать вспомогательный класс, который создаст строку для вас.
public class Test {
private Test() {
// each country for its own
IFilterBuilder filterBuilder = new FilterBuilder();
filterBuilder
.country("UK").or()
.country("FR").or()
.country("CA").or()
.country("US").and()
.number(123).and()
.number(789);
String myFilter = filterBuilder.getResult();
System.out.println(myFilter);
// or a short version with a helper method
IFilterBuilder smartFilterBuilder = new FilterBuilder();
smartFilterBuilder.inAnyCountry("UK", "FR", "CA", "US").and().withNumbers(123, 789);
String result = smartFilterBuilder.getResult();
System.out.println(result);
}
public static void main(String[] args) {
new Test();
}
interface IFilterBuilderBinder {
IFilterBuilder or();
IFilterBuilder and();
}
interface IFilterBuilder {
IFilterBuilderBinder country(String countryName);
IFilterBuilderBinder number(int number);
String getResult();
IFilterBuilderBinder inAnyCountry(String... country);
IFilterBuilderBinder withNumbers(int... numbers);
}
private final static class FilterBuilder implements IFilterBuilder, IFilterBuilderBinder {
private String filter = "&filter=";
public IFilterBuilderBinder country(String countryName) {
filter += "country='" + countryName + "'";
return this;
}
@Override
public IFilterBuilderBinder number(int number) {
filter += "number='" + number + "'";
return this;
}
public String getResult() {
return filter;
}
@Override
public IFilterBuilderBinder inAnyCountry(String... country) {
for (int i = 0; i < country.length; i++) {
country( country[i]);
if(i!=country.length-1){
or();
}
}
return this;
}
@Override
public IFilterBuilderBinder withNumbers(int... numbers) {
for (int i = 0; i < numbers.length; i++) {
number(numbers[i]);
if(i!=numbers.length-1){
and();
}
}
return this;
}
@Override
public IFilterBuilder or() {
filter += " or ";
return this;
}
@Override
public IFilterBuilder and() {
filter += " and ";
return this;
}
}
}