Перегрузка indexOf() для пользовательского созданного ArrayList объектов с использованием одного элемента объекта

Я пытаюсь создать программу списка дел, и у меня возникают проблемы с поиском способа удаления элементов путем поиска определенного элемента.

Я пытаюсь реализовать indexOf(), который будет возвращать индекс элемента, содержащего элемент, искомый в ArrayList of Items, но вместо этого он возвращает только -1, а не найден.

Я перегрузил функцию в своем классе ToDo и перегрузил equals(Object o) и hashCode() в своем классе Item.

Любая помощь будет принята с благодарностью.

import java.util.*;
import java.lang.*;


public class ToDo {

    ArrayList<Item> TodoList = new ArrayList<>();


    static String [] itemData = new String[100];       //to index items added to list
    //itemData = new String[100];
    static int size=0;

    public void addItem(String item, String category, int priority)
    {
        TodoList.add(new Item(item,category,priority));
        itemData[size] = item;  //for indexing
        size++;
    }

    //remove item at specified index spot
    private void removeItem(int i )
    {

        TodoList.remove(i);

    }

    public void getList()
    {
        for (Item item : TodoList)
        {
            System.out.println(item.toString());
        }
    }

    public int getIndex(String item)
    {
        return (TodoList.indexOf(item));

    }

    public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (itemData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(itemData[i]))
                    return i;
        }
        return -1;
    }




    public void print() {
        System.out.println("To-do List: ");
        System.out.println("-----------");
        getList();
        if (TodoList == null) {
            System.out.println("You're all done for today!");
        }
    }



    public static void main(String[] args) {

        ToDo todo = new ToDo();


        todo.addItem("Get pickles", "Shopping", 2);
        todo.addItem("Read book", "School", 3);
        todo.addItem("Send letter", "Other", 1);
        todo.addItem("Buy planner", "School", 4);
        todo.addItem("Get potatoes", "Shopping", 3);
        todo.print();

        System.out.println("------------");
        //todo.removeItem("Read book","School","3");
        //todo.removeItem(1);

        System.out.println("INDEX OF READ BOOK (1) :" + todo.getIndex("ReadBook"));

        //todo.removeItem(todo.getIndex("ReadBook"));
        //todo.print();

        System.out.println("SIZE: " + size);

    }

}
public class Item {


    public int i;
    private String item;
    private String category;
    private int priority;



    //default constructor to initialize
    public Item(String item, String category, int priority){
        this.item = item;
        this.category = category;
        this.priority = priority;
    }



    public String getItem() {
        return item;
    }

    public void setItem(String item) {
        this.item = item;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public int getPriority() {
        return priority;
    }

    //used in order to overload indexOf() method
    //*****************************************************
    @Override
    public boolean equals(Object o) {
        if (o instanceof Item) {
            //item comparison
            Item mo = (Item)o;
            return mo.item.equals(item);
        }
        return false;
    }

    public int hashCode() {
        return java.util.Objects.hashCode(item);
    }

    // *****************************************************

    public String translatePriority()
    {
        if (priority == 1)
            return "low";
        else if (priority == 2)
            return "medium";
        else if (priority == 3)
            return "high";
        else if (priority == 4)
            return "urgent";
        else
            return "invalid priority";

    }



    public String toString() {
        return  "Category : " + category + " || Priority Level: " + translatePriority() + "\nTask : " + item + "\n";
    }





}

Не используйте отдельный массив для вашего индекса. Просто просмотрите ArrayList элементов. И сделайте тип параметра indexOf фактическим типом, который вы хотите (String), а не Object. В противном случае ваш класс сложно использовать, так как неясно, что нужно передать этому методу.

tgdavies 21.12.2020 05:12

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

tgdavies 21.12.2020 05:13

Вы передаете строку TodoList.indexOf(item), но Item.equals() обрабатывает только Items.

001 21.12.2020 05:14
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
388
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Существует ряд проблем с вашим кодом: Вы вызываете indexOf() класса ArrayList, вам нужно перейти на это, чтобы вызвать свой собственный метод

   public int getIndex(String item)
    {
        return (indexOf(item));

    }

и эта строка кода не будет соответствовать ни одному элементу примера, поэтому она вернет -1

todo.getIndex("ReadBook")

может ты хотел написать?

todo.getIndex("Read book")

Довольно много вопросов, чтобы указать здесь.

Вы объявили TodoListArrayList<Item>.

Итак, ваш код:

public int getIndex(String item) {
    return (TodoList.indexOf(item));
}

Всегда будет возвращать -1. Список содержит Item, а не строки.

Вы объявили массив для хранения имен элементов «для индексации». Это не имеет особого смысла. Перебор массива в поисках имени займет столько же времени, сколько и просмотр исходного списка. И у вас будет проблема с синхронизацией индексов.

Лучший вариант — просто сохранить элементы в списке и найти элемент с заданным именем:

IntStream.range(0, ToDoList.size())
    .filter(i -> ToDoList.get(i).getItem().equals(item))
    .findAny().orElse(-1);
Ответ принят как подходящий

Все экземпляры Item содержатся в ToDoList ArrayList. Очевидно, что все, к чему вам нужно получить доступ, можно сделать с помощью этого списка объектов Item. Если ваш поиск должен быть специфичным для переменной экземпляра Item#item, вам нужно будет выполнить итерацию по коллекции ToDoList и сравнить критерии поиска (ReadBooks) с тем, что может содержаться в любом экземпляре Item#item. Если обнаружено совпадение, процесс итерации останавливается и возвращается текущий индекс этой итерации. Это означает, что для вашего метода getIndex() требуются изменения:

public int getIndex(String item) {
    int index = -1;
    String itemString = item.replaceAll("\\s+", "").toLowerCase();
    for (int i = 0; i < TodoList.size(); i++) {
        String listItem = TodoList.get(i).getItem().replaceAll("\\s+", "").toLowerCase();
        // I think it's better to use the String#contains() method
        // instead of the String#indexOf() method.
        if (listItem.contains(itemString)) {
            index = i;
            break;
        }
    }
    return index;
}

Вы можете заметить, что пробелы удалены из любых предоставленных критериев поиска, а строка приведена к нижнему регистру. То же самое делается с каждым экземпляром строки Item#item, полученной в ходе итерации. Это делается для тех случаев, когда критерий поиска указан как "ReadBook", хотя экземпляр элемента явно заполнен "Read book". Приведенный выше код должен найти связь. Вы также заметите, что вместо метода String#indexOf() используется метод String#contains(). Я считаю, что это лучше подходит для этой конкретной ситуации.

Если вы предпочитаете, чтобы ваш поиск был более глобальным по всем переменным-членам экземпляра Item, вам лучше сравнить критерии поиска с экземпляром Item для toString(), например:

String listItem = TodoList.get(i).toString().replaceAll("\\s+", "").toLowerCase();

Однако было бы неплохо изменить формат возвращаемой строки Item#toString(), возможно, на что-то менее подробное, например:

@Override
public String toString() {
    return new StringBuilder("").append(category).append(", ")
            .append(translatePriority()).append(", ").append(item)
            .toString();
}

Другие вопросы по теме