Как переопределить метод toString для отображения элементов в списке в Java?

Я пытался понять это в течение нескольких часов, но я не могу найти ответ, который работает.

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

Я попытался использовать следующее:

 public  String toString(List<?> list) {
String result = " ";
    for (int i = 0; i < list.size(); i++) {
        result += " " + list.get(i);
    }
    return result;
}

Однако это, похоже, не помогает, поскольку я все еще получаю ссылку на хэш-код. Я понимаю, что это потому, что я неправильно переопределяю метод toString; Я получаю сообщение об ошибке, когда включаю аннотацию @Override, но это все, что я смог получить.

Я просмотрел некоторые другие ответы, в которых говорилось, что переопределение метода toString бесполезно в случае списков/коллекций, но не было дано надлежащего руководства для другой альтернативы.

public class WordsContainer {
Collection<String> wordList = new ArrayList<String>();

public void wordGroup1() {
    wordList.add("Ant");
    wordList.add("Almond");
    /// more words
  }

public Collection<String> getRandomWords() {
    wordGroup1();
    LinkedList<String> wordLinkedList = new LinkedList<String>(wordList);
    ArrayList<String> subList = new ArrayList<String>();

    int i = 0;
    while (i < 6) {
        int index = (int) Math.random() * 10;
        if (!subList.contains(wordLinkedList.get(index))) {
            subList.add(wordLinkedList.get(index));
            i++;
        }
    }
    return subList;
}

public  String toString(List<?> list) {
String result = " ";
    for (int i = 0; i < list.size(); i++) {
        result += " " + list.get(i);
      }
    return result;
    }
 }

public class wordsContainerTest {
public static void main(String[] args) {
    wordsContainer list1 = new wordsContainer();

    list1.wordGroup1(); 

    System.out.println(list1);

  }


}

РЕДАКТИРОВАТЬ :

Извините, я забыл упомянуть, что пытался удалить параметры в методе Override следующим образом:

public  String toString() {
  LinkedList<String> list = new LinkedList<>()
   String result = " ";
   for (int i = 0; i < list.size(); i++) {
    result += " " + list.get(i);
}
return result;

} Но когда я запускал код, консоль ничего не отображала. Я понимаю, что это потому, что я создал пустой список, но в этот момент я не знал, что еще делать.


person Frosty619    schedule 29.08.2015    source источник
comment
Просто перестаньте использовать параметр в методе toString(). toString() должен печатать представление класса, что означает, что список должен быть внутри класса, что означает, что вам не нужно его передавать.   -  person takendarkk    schedule 29.08.2015
comment
Если вашей целью является переопределение метода, аннотируйте свой метод с помощью @Override. Так что, если вы на самом деле ничего не переопределяете (что имеет место здесь), вы получите ошибку от компилятора. Посмотрите на javadoc Object.toString(). Ваш метод должен иметь ту же подпись.   -  person JB Nizet    schedule 29.08.2015
comment
Конечно: вы повторяете новый пустой LinkedList, который вы создаете в toString(). Вместо этого вы хотите повторить wordList. Кроме того, когда вы публикуете код, публикуйте код, который действительно компилируется.   -  person JB Nizet    schedule 29.08.2015


Ответы (5)


toString() не имеет аргументов. Перезапишите его так (при условии, что вы расширяете класс List):

@Override
public String toString() {
    String result = " ";
    for (int i = 0; i < this.size(); i++) {
        result += " " + this.get(i);
    }
    return result;
}

ОБНОВЛЕНИЕ 01

Хорошо, кажется, что вы действительно хотите распечатать содержимое списка, инкапсулированного вашим WordsContainer.

Переопределите toString из WordsContainer следующим образом:

@Override
public String toString() {
    StringBuilder sb = new StringBuilder();
    sb.append(" "); // remove this if you do not want two spaces at the front of the returned string
    for (int i = 0; i < this.wordList.size(); i++) {
        sb.append(" " + this.wordList.get(i).toString());
    }
    return sb.toString();
}

Обратите внимание, что вам нужно изменить объявление списка слов, чтобы оно имело тип List<String>.

ОБНОВЛЕНИЕ 02

Это отвечает на последующий вопрос в комментариях.

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

public static String getStringRepresentation(List<String> list) {
    StringBuilder sb = new StringBuilder();
    sb.append(" "); // remove this if you do not want two spaces at the front of the returned string
    for (int i = 0; i < list.size(); i++) {
        sb.append(" " + list.get(i).toString());
    }
    return sb.toString();
}

И используйте этот метод так:

public static void main(String[] args) {
    List<String> list = new ArrayList<String>();
    list.add("foo");
    list.add("bar");
    String listStringRepr = WordsContainer.getStringRepresentation(list);
    System.out.println(listStringRepr);
}
person Janus Varmarken    schedule 29.08.2015
comment
что вы имеете в виду, расширяя класс List (не говоря уже о том, что List — это интерфейс)? - person QuakeCore; 29.08.2015
comment
Поскольку OP пытается переопределить реализацию toString некоторого списка, я предполагаю, что он расширяет реализацию некоторого списка, например. МассивСписок. - person Janus Varmarken; 29.08.2015
comment
@QuakeCore OP создал public class WordsContainer, который не реализует List (и не расширяет какой-либо абстрактный класс). Это новый Класс. Итак, здесь переопределяется метод toString() класса Object. - person Wololo; 29.08.2015
comment
Да, @QuakeCore, Сауд прав, я не реализую List как интерфейс, но это мой единственный план действий? - person Frosty619; 29.08.2015
comment
Проблема здесь в том, что ваш вопрос на самом деле не соответствует тому, что вы на самом деле хотите сделать. Позвольте мне обновить ответ, я думаю, что теперь понимаю, что вы хотите сделать. - person Janus Varmarken; 29.08.2015
comment
Спасибо за быстрый ответ; Я думаю, вы имели в виду public String toString вместо public void? В любом случае, я попробовал обновленный подход и теперь могу распечатать список. Однако, если я также хочу распечатать список случайных слов, должен ли я добавить еще одно предостережение к методу toString? Есть ли способ переопределить метод toString, чтобы я мог распечатать любой список без повторного изменения toString? - person Frosty619; 29.08.2015
comment
Правильно, я перепутал тип возврата, извините. Конечно, это должен быть общедоступный String toString. - person Janus Varmarken; 29.08.2015
comment
Не изобретайте велосипед: return list.stream().collect(Collectors.joining(" ")); - person Bohemian♦; 29.08.2015
comment
@ user2430656 Обновленный ответ с ответом на ваш дополнительный вопрос. - person Janus Varmarken; 29.08.2015
comment
@Bohemian: умный, не знал этого :) - person Janus Varmarken; 29.08.2015
comment
OP здесь, вы говорите, что вместо этого все элементы в списке должны быть добавлены в main; Я хочу, чтобы основная часть была как можно короче. Кроме того, я не понимаю использование метода getStringRepresentation, поскольку я добавляю свой код в main и вызываю этот метод только для вывода списка. На данный момент кажется более эффективным просто использовать System.out.println(list). Кстати большое спасибо за подробные ответы. - person Frosty619; 29.08.2015
comment
@ Frosty619 Я не совсем понимаю, о чем вы спрашиваете. Добавление элементов в main было сделано просто для того, чтобы продемонстрировать, как вы можете использовать метод getStringRepresentation для создания строкового представления любого заданного списка строк. Если ответ помог вам найти решение, отметьте его как принятый. - person Janus Varmarken; 29.08.2015
comment
Если вы хотите объединить его в одну строку, вы, конечно, также можете написать System.out.println(WordsContainer.getStringRepresentation(list));. Это просто вопрос стиля — абсолютно никакой разницы в плане производительности. - person Janus Varmarken; 29.08.2015
comment
Благодарю вас! Вы очень помогли. - person Frosty619; 30.08.2015

Вы не соответствуете подписи Object.toString(). (Обычно я позволяю своей IDE генерировать заглушку, очень помогает ;))

Просто добавьте это в свой существующий код:

@Override
public String toString() {
    return "WordsContainer{" +
            "wordList=(" + toString(wordList) + ")}";
}

Однако вам придется объявить wordList как List.

ОБНОВЛЕНИЕ:

Чтобы уточнить последнее замечание в исходном ответе:

В вашей собственной оболочке WordsContainer вы объявляете wordList как

Collection<String> wordList = new ArrayList<String>();

в то время как в вашей собственной попытке реализовать toString вы используете List<?> в качестве типа параметра. Следовательно, приведенный выше код не будет работать без еще одного рефакторинга. Либо объявите wordList как List<String>

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

или реорганизуйте свой toString(), чтобы использовать Collection<?> в качестве аргумента:

public String toString(Collection<?> list) {
    String result = " ";

    for (Object item : list) {
        result += " " + item.toString();
    }
    return result;
}
person Sascha Kolberg    schedule 29.08.2015
comment
Не разрешено создавать экземпляр объекта в виде списка в качестве его интерфейса, поэтому я не уверен, что следую. - person Frosty619; 29.08.2015

Поскольку у вас есть параметр для вашего метода toString(), это больше не метод toString() класса Object. Это новый метод, и он работает как перегруженная версия Object toString(), а не переопределенная версия. Удалите параметр. Чтобы правильно работать с toString(), вам нужно иметь точно такую ​​же сигнатуру метода -

public String toString(){
   //implmentation
}
person Razib    schedule 29.08.2015

Просто вызовите toString() с самим элементом List. Вот так:

import java.util.List;
import java.util.LinkedList;
public class WordList {
    List<String> list = new LinkedList<String>();
    public static void main(String []args) {
       System.out.println(new WordList());
    }

    @Override
    public String toString() {
        String result = "";
        list.add("Hello");

        list.add("World");
        for (int i = 0; i < list.size(); i++) {
            result += " " + list.get(i).toString();//call toString on element of the list
        }
        return result;
    }
}

Вывод: «Привет, мир»

person exception_catcher    schedule 29.08.2015

package listtostringmethod;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
public class ListToStringMethod {

    enter code here
    public static void main(String[] args) {
        // TODO code application logic here
        //List<String> s = Arrays.asList("a","b","c");
        //s.toString();

        MyList myList = new MyList();
            myList.add("a");
            myList.add("b");
        //myList.toString();
        System.out.println(myList.toString());
    }

}

class MyList extends ArrayList {
    @Override
    public String toString (){
        StringBuffer retVal = new StringBuffer();
        Iterator iterator = this.iterator();
            while (iterator.hasNext()){
                retVal.append(iterator.next()+",");
            }
        return retVal.toString();
    }
}

Код прямолинеен. Надеюсь, это поможет вам.

person nawazish-stackoverflow    schedule 29.08.2015