代码之家  ›  专栏  ›  技术社区  ›  froadie

在java中从列表构建分隔字符串的最佳方法

  •  2
  • froadie  · 技术社区  · 14 年前

    我有一个对象列表,每个对象都有一个字符串属性。例如,我有一个 List<Person> 以及每个 Person 有一个 firstName 财产。我想构建一个逗号分隔的带引号的字符串,如下所示:

    'James', 'Lily', 'Michael'
    

    9 回复  |  直到 14 年前
        1
  •  3
  •   hb2pencil    14 年前

    如果您想简单地手动执行,可以执行以下操作:

    String mystr = "";
    for(int i = 0; i < personlist.size(); i++) {
      mystr += "\'" + personlist.get(i).firstName + "\'";
      if(i != (personlist.size() - 1)) {
        mystr += ", ";
      }
    }
    

    现在mystr包含了您的列表。请注意,只有在不处理列表中的最后一个元素时(使用index personlist.size()-1),才会添加逗号。

    当然,有更优雅/有效的方法来实现这一点,但在我看来,这是最清晰的方法。

        2
  •  20
  •   Eran Medan    12 年前

    Apache StringUtils )

    String joined = "'" + StringUtils.join(arrayOrList,"','") + "'";
    
        3
  •  2
  •   BalusC    14 年前

    用最直接的方法。有一个 StringBuilder ,在 List

    StringBuilder builder = new StringBuilder();
    for (int i = 0; i < persons.size(); i++) {
        builder.append("'").append(persons.get(i)).append("'");
        if (i < persons.size() - 1) {
            builder.append(", ");
        }
    }
    String string = builder.toString();
    

    或者,也可以使用 Iterator

    StringBuilder builder = new StringBuilder();
    for (Iterator<Person> iter = persons.iterator(); iter.hasNext();) {
        builder.append("'").append(iter.next()).append("'");
        if (iter.hasNext()) {
            builder.append(", ");
        }
    }
    String string = builder.toString();
    

    请注意,使用 字符串拼接 优先于使用 +=

        4
  •  2
  •   Mike Samaras    8 年前

    Jdk8 Lambda的解决方案:

    String quotedAndDelimited = Arrays.stream(values).collect(Collectors.joining("\",\"","\"","\""));
    

    这将提供“,”作为分隔符,以及的前缀和后缀。

        5
  •  1
  •   morisil    14 年前

    下面是带期望的单元测试:

    import static java.util.Arrays.*;
    import static org.hamcrest.CoreMatchers.*;
    import static org.junit.Assert.*;   
    import org.junit.Test;
    
    
    public class JoinerTest {
    
        private static final Converter<Person, String> PERSON_CONVERTER =
            new Converter<Person, String>() {
                @Override
                public String convert(Person object) {
                    return object.getFirstName();
                }
        };
    
        @Test
        public void shouldPresentFirstNames() {
            // given
            Person person1 = new Person();
            person1.setFirstName("foo");
            Person person2 = new Person();
            person2.setFirstName("bar");
            Joiner<Person> joiner = new Joiner<Person>(", ", "\'");
    
            // when
            String firstNames = joiner.join(PERSON_CONVERTER,
                            asList(person1, person2));
    
            // then
            assertThat(firstNames, is("\'foo\', \'bar\'"));
        }
    
    }
    

    转换器只是一个接口:

    public interface Converter<F, T> {
        T convert(F object);
    }
    

    public class Joiner<T> {
    
        private final String delimiter;
    
        private final String quote;
    
        public Joiner(String delimiter, String quote) {
            this.delimiter = delimiter;
            this.quote = quote;
        }
    
        public String join(Converter<T, String> converter, Iterable<T> objects) {
            StringBuilder builder = new StringBuilder();
            for (T object : objects) {
                String string = converter.convert(object);
                builder.append(quote);
                builder.append(string);
                builder.append(quote);
                builder.append(delimiter);
            }
            if (builder.length() > 0) {
                builder.setLength(builder.length() - delimiter.length());
            }
            return builder.toString();
        }
    }
    

    通过使用不同的转换器,很容易连接不同类型的属性。

        6
  •  1
  •   Edwin Buck    13 年前

    我喜欢

    if (list != null) {
      Iterator iter = list.iter();
      if (iter.hasNext()) {
        buffer.append(iter.next());
        while (iter.hasNext()) {
          buffer.append(", ");
          buffer.append(iter.next());
        }
      }
    }
    

    这样做的主要优点是90%的执行时间可能会在内部while循环中完成,而且这个解决方案只需要一次比较就可以确定是否需要退出内部while循环。

    其他解决方案也可以,但解决方案如下所示:

    while (iter.hasNext()) {
      buffer.append(iter.next());
      if (iter.hasNext()) {
        buffer.append(", ");
      }
    }
    

    在while循环中嵌入不必要的if语句。这意味着必须对每个元素进行额外的比较,而唯一不同的元素是最后一个。

    通过将用于检查元素是否是最后一个元素的比较转移到存在多个元素时的比较,我们只需要为除第一个元素以外的每个元素移动附加的“,”到前置的“,”

        7
  •  0
  •   TheDevOpsGuru    14 年前

    您可以遍历列表中的每个项目,并使用StringBuilder.append()方法将每个名称添加到列表中。这将使用string类创建一个新的字符串实例,因为字符串是不可变的。

    2) 使用list.size()获取列表中的项数

    int listSize = personList.size()
    

    3) 将第一个开头的paren和引号添加到字符串中

    StringBuilderinstance.append("('")
    

    4) 使用for循环并将每个名称、结束引号、逗号和开始引号添加到stringBuilder实例中,然后调用append方法检查i是否等于listSize如果您位于最后一个索引,请仅附加firstname、quote和closing paren:

    for(int i = 0, i<listSize, i++)
    {    
        if(i == listSize - 1)
            StringBuilderinstance.append(firstName + "')")
        else    
            StringBuilderinstance.append(firstName + "', '")
    }
    
        8
  •  0
  •   Tom    14 年前

    private static final char QUOTE = '\'';
    private static final String SEPARATOR = ", ";
    
    public static String join(List<Person> people) {
        if (people.isEmpty()) {
            return "";
        }
        final StringBuilder builder = new StringBuilder();
        for (Person person : people) {
            builder.append(QUOTE);
            builder.append(person.getFirstName());
            builder.append(QUOTE);
            builder.append(SEPARATOR);
        }
        builder.setLength(builder.length() - SEPARATOR.length());
        return builder.toString();
    }
    

        9
  •  0
  •   Tom    8 年前

    我建议你先在你的 Person

    Person {
        //...
        String toListEntry() {
            return "\'" + firstName + "\'";
        }
    }
    

    现在您可以使用:

    List<Person> list = //... get the list
    StringBuilder buf = new StringBuilder(list.get(0).toListEntry());
    
    for(int i = 1; i < list.size(); i++)
        buf.append(" , " + list.get(i).toListEntry());
    
    String stringList = buf.toString();