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

#java #arraylist #overloading #indexof

#java #arraylist #перегрузка #indexof

Вопрос:

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

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

Я перегрузил функцию в своем классе 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";
    }





}
 

Комментарии:

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

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

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

Ответ №1:

Все экземпляры Item содержатся в массиве ToDoList ArrayList. Очевидно, что все, что вам нужно для доступа, может быть сделано через этот список объектов Item. Если ваш поиск должен быть специфичным для переменной экземпляра Item#item, вам нужно будет выполнить итерацию по коллекции ToDoList и сравнить критерии поиска (книги для чтения) с тем, что может содержаться в любом экземпляре 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() . Я считаю, что это лучше подходит для данной конкретной ситуации.

Если вы предпочитаете, чтобы ваш поиск был более глобальным по всем переменным-членам экземпляра элемента, тогда вам было бы лучше сравнить критерии поиска с экземпляром элемента 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();
}
 

Ответ №2:

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

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

    }
 

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

 todo.getIndex("ReadBook")
 

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

 todo.getIndex("Read book")
 

Ответ №3:

Здесь следует указать на довольно много проблем.

Вы объявили TodoList , что это ArrayList<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);