Что лучший способ состоит в том, чтобы создать строку разграниченных объектов в Java?

Исключение нулевого указателя - это индикатор того, что вы используете объект, не инициализируя его.

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

public class Student {

    private int id;

    public int getId() {
        return this.id;
    }

    public setId(int newId) {
        this.id = newId;
    }
}

Приведенный ниже код дает вам исключение с нулевым указателем.

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}

Поскольку вы используете Obj_Student, но вы забыли инициализировать его, как в правильном коде, показанном ниже:

public class School {

    Student obj_Student;

    public School() {
        try {
            obj_Student = new Student();
            obj_Student.setId(12);
            obj_Student.getId();
        }
        catch(Exception e) {
            System.out.println("Null Pointer ");
        }
    }
}
304
задан 2 revs, 2 users 98% 20 August 2015 в 01:40
поделиться

23 ответа

Пред Java 8:

свободное городское население Apache Ленг является Вашим другом здесь - это предоставляет метод соединения, очень похожий на тот, к которому Вы обращаетесь в Ruby:

StringUtils.join(java.lang.Iterable,char)

<час>

Java 8:

Java 8 обеспечивает присоединение из поля через StringJoiner и String.join(). Отрывки ниже показывают, как можно использовать их:

StringJoiner

StringJoiner joiner = new StringJoiner(",");
joiner.add("01").add("02").add("03");
String joinedString = joiner.toString(); // "01,02,03"
<час>

String.join(CharSequence delimiter, CharSequence... elements))

String joinedString = String.join(" - ", "04", "05", "06"); // "04 - 05 - 06"
<час>

String.join(CharSequence delimiter, Iterable<? extends CharSequence> elements)

List<String> strings = new LinkedList<>();
strings.add("Java");strings.add("is");
strings.add("cool");
String message = String.join(" ", strings);
//message returned is: "Java is cool"
520
ответ дан edwardmlyte 23 November 2019 в 01:21
поделиться

Можно попробовать что-то вроде этого:

StringBuilder sb = new StringBuilder();
if (condition) { sb.append("elementName").append(","); }
if (anotherCondition) { sb.append("anotherElementName").append(","); }
String parameterString = sb.toString();
0
ответ дан martinatime 23 November 2019 в 01:21
поделиться

Так в основном что-то вроде этого:

public static String appendWithDelimiter(String original, String addition, String delimiter) {

if (original.equals("")) {
    return addition;
} else {
    StringBuilder sb = new StringBuilder(original.length() + addition.length() + delimiter.length());
        sb.append(original);
        sb.append(delimiter);
        sb.append(addition);
        return sb.toString();
    }
}
0
ответ дан killdash10 23 November 2019 в 01:21
поделиться

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

Вниз ниже более универсальный подход, если можно создать список параметров ПРЕЖДЕ, ЧЕМ сделать какое-либо разграничивание параметра.

// Answers real question
public String appendWithDelimiters(String delimiter, String original, String addition) {
    StringBuilder sb = new StringBuilder(original);
    if(sb.length()!=0) {
        sb.append(delimiter).append(addition);
    } else {
        sb.append(addition);
    }
    return sb.toString();
}


// A more generic case.
// ... means a list of indeterminate length of Strings.
public String appendWithDelimitersGeneric(String delimiter, String... strings) {
    StringBuilder sb = new StringBuilder();
    for (String string : strings) {
        if(sb.length()!=0) {
            sb.append(delimiter).append(string);
        } else {
            sb.append(string);
        }
    }

    return sb.toString();
}

public void testAppendWithDelimiters() {
    String string = appendWithDelimitersGeneric(",", "string1", "string2", "string3");
}
0
ответ дан Mikezx6r 23 November 2019 в 01:21
поделиться

Ваш подход не слишком плох, но необходимо использовать StringBuffer вместо того, чтобы использовать + знак. + имеет большой недостаток, что новый Строковый экземпляр создается для каждой единственной операции. Чем дольше Ваша строка становится, тем больше издержки. Так использование StringBuffer должно быть самым быстрым путем:

public StringBuffer appendWithDelimiter( StringBuffer original, String addition, String delimiter ) {
        if ( original == null ) {
                StringBuffer buffer = new StringBuffer();
                buffer.append(addition);
                return buffer;
        } else {
                buffer.append(delimiter);
                buffer.append(addition);
                return original;
        }
}

После того, как Вы закончили создавать свою строку просто, называют toString () на возвращенном StringBuffer.

0
ответ дан Yaba 23 November 2019 в 01:21
поделиться

Вместо того, чтобы использовать конкатенацию строк, необходимо использовать StringBuilder, если код не является поточным, и StringBuffer, если это.

0
ответ дан Aaron 23 November 2019 в 01:21
поделиться

Вы делаете это немного более сложным, чем это должно быть. Давайте запустимся с конца Вашего примера:

String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );

С небольшим изменением использования StringBuilder вместо Строки, это становится:

StringBuilder parameterString = new StringBuilder();
if (condition) parameterString.append("elementName").append(",");
if (anotherCondition) parameterString.append("anotherElementName").append(",");
...

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

if (parameterString.length() > 0) 
    parameterString.deleteCharAt(parameterString.length() - 1);

И наконец, получите строку, которую Вы хотите с

parameterString.toString();

, Вы могли также заменить"", во втором вызове для добавления с универсальной строкой разделителя, которая может быть установлена на что-либо. Если у Вас есть список вещей, Вы знаете, что необходимо добавить (неусловно), Вы могли поместить этот код в методе, который берет список строк.

0
ответ дан 23 November 2019 в 01:21
поделиться

Так несколько вещей Вы могли бы сделать для привыкания, что кажется, что Вы ищете:

1) Расширяют класс Списка - и добавляют метод соединения к нему. Метод соединения просто сделал бы работу конкатенации и добавления разделителя (который мог быть параметрическим усилителем к методу соединения)

2), похоже, что Java 7 будет добавляющими дополнительными методами к Java - который позволяет Вам только для присоединения определенного метода на классе: таким образом, Вы могли записать, что метод соединения и добавляет его как дополнительный метод для Списка или даже к Набору.

Решением 1 является, вероятно, единственное реалистическое, теперь, хотя, так как Java 7 еще не отсутствует:), Но это должно работать просто великолепно.

Для использования обоих из них Вы просто добавили бы все свои объекты к Списку или Набору, как обычно, и затем назвали бы новый пользовательский метод 'присоединиться' к ним.

0
ответ дан user13276 23 November 2019 в 01:21
поделиться
//Note: if you have access to Java5+, 
//use StringBuilder in preference to StringBuffer.  
//All that has to be replaced is the class name.  
//StringBuffer will work in Java 1.4, though.

appendWithDelimiter( StringBuffer buffer, String addition, 
    String delimiter ) {
    if ( buffer.length() == 0) {
        buffer.append(addition);
    } else {
        buffer.append(delimiter);
        buffer.append(addition);
    }
}


StringBuffer parameterBuffer = new StringBuffer();
if ( condition ) { 
    appendWithDelimiter(parameterBuffer, "elementName", "," );
}
if ( anotherCondition ) {
    appendWithDelimiter(parameterBuffer, "anotherElementName", "," );
}

//Finally, to return a string representation, call toString() when returning.
return parameterBuffer.toString(); 
0
ответ дан MetroidFan2002 23 November 2019 в 01:21
поделиться

С переменной Java 5 args, таким образом, Вы не должны наполнять все свои строки в набор или массив явно:

import junit.framework.Assert;
import org.junit.Test;

public class StringUtil
{
    public static String join(String delim, String... strings)
    {
        StringBuilder builder = new StringBuilder();

        if (strings != null)
        {
            for (String str : strings)
            {
                if (builder.length() > 0)
                {
                    builder.append(delim).append(" ");
                }
                builder.append(str);
            }
        }           
        return builder.toString();
    }
    @Test
    public void joinTest()
    {
        Assert.assertEquals("", StringUtil.join(",", null));
        Assert.assertEquals("", StringUtil.join(",", ""));
        Assert.assertEquals("", StringUtil.join(",", new String[0]));
        Assert.assertEquals("test", StringUtil.join(",", "test"));
        Assert.assertEquals("foo, bar", StringUtil.join(",", "foo", "bar"));
        Assert.assertEquals("foo, bar, x", StringUtil.join(",", "foo", "bar", "x"));
    }
}
1
ответ дан Stu Thompson 23 November 2019 в 01:21
поделиться

То, почему Вы не делаете в Java того же самого, которое Вы делаете в рубине, который создает разделитель, разделило строку только после добавления всех частей к массиву?

ArrayList<String> parms = new ArrayList<String>();
if (someCondition) parms.add("someString");
if (anotherCondition) parms.add("someOtherString");
// ...
String sep = ""; StringBuffer b = new StringBuffer();
for (String p: parms) {
    b.append(sep);
    b.append(p);
    sep = "yourDelimiter";
}

можно хотеть переместить это для цикла в отдельном вспомогательном методе, и также использовать StringBuilder вместо StringBuffer...

Редактирование : зафиксированный порядок добавляет.

1
ответ дан agnul 23 November 2019 в 01:21
поделиться

Я использовал бы Google Collections. Существует хорошее средство Соединения.
http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/base/Join.html

, Но если я хотел записать его самостоятельно,

package util;

import java.util.ArrayList;
import java.util.Iterable;
import java.util.Collections;
import java.util.Iterator;

public class Utils {
    // accept a collection of objects, since all objects have toString()
    public static String join(String delimiter, Iterable<? extends Object> objs) {
        if (objs.isEmpty()) {
            return "";
        }
        Iterator<? extends Object> iter = objs.iterator();
        StringBuilder buffer = new StringBuilder();
        buffer.append(iter.next());
        while (iter.hasNext()) {
            buffer.append(delimiter).append(iter.next());
        }
        return buffer.toString();
    }

    // for convenience
    public static String join(String delimiter, Object... objs) {
        ArrayList<Object> list = new ArrayList<Object>();
        Collections.addAll(list, objs);
        return join(delimiter, list);
    }
}

, я думаю, что это работает лучше с объектным набором, так как теперь Вы не должны преобразовывать свои объекты в строки перед присоединением к ним.

10
ответ дан Eric Normand 23 November 2019 в 01:21
поделиться

Можно обобщить его, но существует, не участвуют в Java, как Вы хорошо говорите.

Это могло бы работать лучше.

public static String join(Iterable<? extends CharSequence> s, String delimiter) {
    Iterator<? extends CharSequence> iter = s.iterator();
    if (!iter.hasNext()) return "";
    StringBuilder buffer = new StringBuilder(iter.next());
    while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
    return buffer.toString();
}
20
ответ дан DaveShaw 23 November 2019 в 01:21
поделиться

Используйте подход на основе java.lang.StringBuilder ! ("Изменяемая последовательность символов".)

Как Вы упомянутый, все те конкатенации строк создают Строки на всем протяжении. StringBuilder не сделает этого.

, Почему StringBuilder вместо StringBuffer ? От StringBuilder javadoc:

, Где возможно, рекомендуется, чтобы этот класс использовался в предпочтении к StringBuffer, поскольку это будет быстрее являться объектом большинства реализаций.

15
ответ дан Stu Thompson 23 November 2019 в 01:21
поделиться

Необходимо, вероятно, использовать StringBuilder с append метод для построения результата, но иначе это столь хорошо из решения, как Java должен предложить.

1
ответ дан newdayrising 23 November 2019 в 01:21
поделиться

свободное городское население Apache класс StringUtils имеет метод соединения.

8
ответ дан 23 November 2019 в 01:21
поделиться

Можно использовать Java StringBuilder тип для этого. Существует также StringBuffer, но это содержит дополнительную логику потокобезопасности, которая является часто ненужной.

3
ответ дан Tim Cooper 23 November 2019 в 01:21
поделиться

Используйте StringBuilder, и класс Separator

StringBuilder buf = new StringBuilder();
Separator sep = new Separator(", ");
for (String each : list) {
    buf.append(sep).append(each);
}

Разделитель обертывает разделитель. Разделитель возвращается методом Разделителя toString, если на первом вызове, который возвращает пустую строку!

Исходный код для класса Separator

public class Separator {

    private boolean skipFirst;
    private final String value;

    public Separator() {
        this(", ");
    }

    public Separator(String value) {
        this.value = value;
        this.skipFirst = true;
    }

    public void reset() {
        skipFirst = true;
    }

    public String toString() {
        String sep = skipFirst ? "" : value;
        skipFirst = false;
        return sep;
    }

}
3
ответ дан 2 revs 23 November 2019 в 01:21
поделиться

Почему бы не записать Ваше собственное соединение () метод? Это взяло бы в качестве набора параметров Строк и Строки разделителя. В рамках метода выполняют итерации по набору и создают Ваш результат в StringBuffer.

2
ответ дан Dave Costa 23 November 2019 в 01:21
поделиться

Вы могли записать немного служебного метода стиля соединения, который работает над java.util. Списки

public static String join(List<String> list, String delim) {

    StringBuilder sb = new StringBuilder();

    String loopDelim = "";

    for(String s : list) {

        sb.append(loopDelim);
        sb.append(s);            

        loopDelim = delim;
    }

    return sb.toString();
}

Тогда использование это как так:

    List<String> list = new ArrayList<String>();

    if( condition )        list.add("elementName");
    if( anotherCondition ) list.add("anotherElementName");

    join(list, ",");
52
ответ дан Rob Dickerson 23 November 2019 в 01:21
поделиться
public static String join(String[] strings, char del)
{
    StringBuffer sb = new StringBuffer();
    int len = strings.length;
    boolean appended = false;
    for (int i = 0; i < len; i++)
    {
        if (appended)
        {
            sb.append(del);
        }
        sb.append(""+strings[i]);
        appended = true;
    }
    return sb.toString();
}
-2
ответ дан izb 23 November 2019 в 01:21
поделиться

используя Доллар просто как набор:

String joined = $(aCollection).join(",");

NB: он работает также для массива и других типов данных

Реализация

Внутренне он использует очень аккуратный трюк:

@Override
public String join(String separator) {
    Separator sep = new Separator(separator);
    StringBuilder sb = new StringBuilder();

    for (T item : iterable) {
        sb.append(sep).append(item);
    }

    return sb.toString();
}

класс Separator возвращает пустую строку только при первом вызове, затем возвращает разделитель:

class Separator {

    private final String separator;
    private boolean wasCalled;

    public Separator(String separator) {
        this.separator = separator;
        this.wasCalled = false;
    }

    @Override
    public String toString() {
        if (!wasCalled) {
            wasCalled = true;
            return "";
        } else {
            return separator;
        }
    }
}
0
ответ дан 23 November 2019 в 01:21
поделиться

Небольшое улучшение [скорости] версии из izb:

public static String join(String[] strings, char del)
{
    StringBuilder sb = new StringBuilder();
    int len = strings.length;

    if(len > 1) 
    {
       len -= 1;
    }else
    {
       return strings[0];
    }

    for (int i = 0; i < len; i++)
    {
       sb.append(strings[i]).append(del);
    }

    sb.append(strings[i]);

    return sb.toString();
}
0
ответ дан 23 November 2019 в 01:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: