Java 避免重复构建字符串的最佳方法

Java 避免重复构建字符串的最佳方法,java,string,url,string-building,Java,String,Url,String Building,我有一个硬编码的字符串,将在URL中使用,我想知道构建这个字符串的最佳方法是什么,而不必重复单词country,或,and,number?这是一个简短的版本,因为有更多的国家和数字将进入URL String url = "&filter=country='UK' or " + "country='FR' or " + "country='CA' or " +

我有一个硬编码的字符串,将在URL中使用,我想知道构建这个字符串的最佳方法是什么,而不必重复单词
country,或,and,number
?这是一个简短的版本,因为有更多的国家和数字将进入URL

String url = "&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();

您可以使用
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);

您还可以创建一个帮助器类来为您构建字符串

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;
    }
}
公共类测试{
私人测试(){
//每个国家都有自己的利益
IFilterBuilder filterBuilder=新的filterBuilder();
过滤器生成器
.国家(“英国”)。或()
.国家(“FR”)。或()
.国家(“CA”)。或()
.国家(“美国”)和()
.编号(123)。及()
.电话号码(789);
字符串myFilter=filterBuilder.getResult();
System.out.println(myFilter);
//或者是带有帮助器方法的简短版本
IFilterBuilder smartFilterBuilder=新的FilterBuilder();
smartFilterBuilder。位于任何国家(“英国”、“法国”、“加利福尼亚”、“美国”)。和();
字符串结果=smartFilterBuilder.getResult();
系统输出打印项次(结果);
}
公共静态void main(字符串[]args){
新测试();
}
接口IFilterBuilderBinder{
IFilterBuilder或();
IFilterBuilder和();
}
界面过滤器生成器{
IFilterBuilderBinder国家(字符串countryName);
IFilterBuilderBinder编号(整数);
字符串getResult();
IFilterBuilderBinder位于任何国家(字符串…国家/地区);
IFilterBuilderBinder带数字(整数…数字);
}
私有最终静态类FilterBuilder实现IFilterBuilder、IFilterBuilder和IFilterBuilderBinder{
私有字符串筛选器=“&filter=”;
公共IFilterBuilderBinder国家(字符串countryName){
过滤器+=“国家=”+“国家名+”;
归还这个;
}
@凌驾
公共IFilterBuilderBinder编号(整数){
过滤器+=“数字=”+“数字+”;
归还这个;
}
公共字符串getResult(){
回流过滤器;
}
@凌驾
国家/地区的公共IFilterBuilderBinder(字符串…国家/地区){
对于(int i=0;i

}

首先使用
StringBuilder
类,其次,如果不想重复关键字,您可以使用常量。您也可以使用一些众所周知的Java HTTP库来构建参数字符串,如本教程所述,如果必须删除最后一个“and”/“或”?@MichaelMarkidis,您还可以使用一个索引循环,并为列表中的最后一项添加一个条件,以不添加“and/or”,但在我看来,这完全是冗长的。
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;
    }
}