Как эффективно объединить несколько переменных String каждая из списка объектов? - PullRequest
0 голосов
/ 03 сентября 2018

Я хотел бы просмотреть список объектов и объединить несколько строк для каждой переменной:

final StringBuilder xBuilder = new StringBuilder();
final StringBuilder yBuilder = new StringBuilder();
final StringBuilder zBuilder = new StringBuilder();

someObjects.forEach(obj -> {
  A a = obj.getA();
  xBuilder.append(obj.getX() + ",");
  yBuilder.append(obj.getY() + ",");
  zBuilder.append(a.getZ() + ",");
});

Есть ли более эффективный способ, чем создание нескольких StringBuilders для каждой переменной?

Ответы [ 4 ]

0 голосов
/ 03 сентября 2018

Поскольку вы объединяете 3 разных свойства объекта, вам нужно использовать 3 разных StringBuilder экземпляра (или StringJoiner). Вы можете повторить список объектов 3 раза, по одному для каждого свойства, или, если вы хотите повторить список только один раз (несмотря на то, что обход списка чрезвычайно дешев), вы можете использовать либо свой собственный подход, либо традиционный foreach.

Или вы также можете использовать код, который я показываю ниже, который семантически эквивалентен другим ответам, за исключением того, что он позволяет отделить процесс конкатенации от итерации (если вам это вообще нужно):

StringBuilder xBuilder = new StringBuilder(); // no need to use final since
StringBuilder yBuilder = new StringBuilder(); // these instances are 
StringBuilder zBuilder = new StringBuilder(); // effectively final

Consumer<SomeObject> action = ((Consumer<SomeObject>) obj -> 
    xBuilder.append(obj.getX() + ","))
        .andThen(obj -> yBuilder.append(obj.getY() + ","))
        .andThen(obj -> zBuilder.append(obj.getA().getZ() + ","));

Затем вы можете передать action (т. Е. Некоторому методу, который не имеет видимости над строителями) и просто сделать:

someObjects.forEach(action);
0 голосов
/ 03 сентября 2018

Есть ли более эффективный способ, чем создание нескольких StringBuilders для каждой переменной?

Нет более эффективного способа, чем создать что-то для каждой из переменных.

Не используйте forEach здесь: нет преимущества перед простым старым циклом (вопрос о различиях см. здесь ):

final StringBuilder xBuilder = new StringBuilder();
final StringBuilder yBuilder = new StringBuilder();
final StringBuilder zBuilder = new StringBuilder();

for (SomeObject obj : someObjects) {
  A a = obj.getA();

  // Use two appends, rather than concatentating then appending.
  xBuilder.append(obj.getX()).append(",");

  yBuilder.append(obj.getY()).append(",");
  zBuilder.append(a.getZ()).append(",");

}
0 голосов
/ 03 сентября 2018

Метод Collectors.joining () будет внутренне использовать StringJoiner для добавления строк с переданным разделителем, как здесь ','.

someObjects.stream().collect(Collectors.joining(","));
0 голосов
/ 03 сентября 2018

Ну, вы делаете хотите 3 отдельные строки здесь, так что выглядит прекрасно, если вы создаете 3 StringBuilder (s) .. Вы можете альтернативно использовать StringJoiner, хотя:

StringJoiner xJoiner = new StringJoiner(",");
someObjects.forEach(obj -> {
    xJoiner.join(obj.getX();
});
...