Как вернуть позицию объекта по именам? - PullRequest
1 голос
/ 31 марта 2020

У меня есть метод, который подсчитывает позицию предмета, сравнивая названия других предметов, но я хотел знать, есть ли более простой способ сделать это?

  //  arr.get(0) : Item0:"nameA"
  //  arr.get(1) : Item1:"nameB"
  //  arr.get(2) : Item2:"nameB"
  //  arr.get(3) : Item3:"nameB"
  //  arr.get(4) : Item4:"nameC"
  //  arr.get(5) : Item5:"nameC"
  //  arr.get(6) : Item6:"nameB"

  //  If I set (arr, Item2) : should return 2 ("nameB")
  //  If I set (arr, Item6) : should return 4 ("nameB")
  //  If I set (arr, Item5) : should return 2 ("nameC")

public int positionOfItemByName(Item[] array, Item item) {
    int cpt = 0;
    for (int i = 0; i < arr.length; i++) {
        if (array[i].name().indexOf( item.name() ) == -1) continue;
        cpt++;
        if (array[i] == item) break;
    }
    return cpt;
}

Спасибо!

Ответы [ 3 ]

2 голосов
/ 31 марта 2020

Если посмотреть на ваше требование, название метода, positionOfItemByName не будет подходящим. С точки зрения исполнения не имеет значения, какое имя вы выберете. Тем не менее, имя должно быть как можно более информативным.

Ниже приведен лог c для удовлетворения ваших требований:

public static int countOfItemByNameAndPosition(Item[] array, Item item) {
    List<Item> arr = new ArrayList<Item>(Arrays.asList(array));
    int cpt = 0;
    int index = arr.indexOf(item);
    if (index != -1) {
        for (int i = 0; i < arr.size() && i <= index; i++) {
            if (arr.get(i).name.equals(item.name)) {
                cpt++;
            }
        }
    }
    return cpt;
}

Демо

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

class Item {
    String name;

    public Item(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Item [name=" + name + "]";
    }
}

public class Main {
    public static void main(String[] args) {
        Item item0 = new Item("nameA");
        Item item1 = new Item("nameB");
        Item item2 = new Item("nameB");
        Item item3 = new Item("nameB");
        Item item4 = new Item("nameC");
        Item item5 = new Item("nameC");
        Item item6 = new Item("nameB");

        Item[] array = { item0, item1, item2, item3, item4, item5, item6 };
        System.out.println(countOfItemByNameAndPosition(array, item2));
        System.out.println(countOfItemByNameAndPosition(array, item6));
        System.out.println(countOfItemByNameAndPosition(array, item5));
    }

    public static int countOfItemByNameAndPosition(Item[] array, Item item) {
        List<Item> arr = new ArrayList<Item>(Arrays.asList(array));
        int cpt = 0;
        int index = arr.indexOf(item);
        if (index != -1) {
            for (int i = 0; i < arr.size() && i <= index; i++) {
                if (arr.get(i).name.equals(item.name)) {
                    cpt++;
                }
            }
        }
        return cpt;
    }
}

Выход:

2
4
2

Использование Stream API:

public static int countOfItemByNameAndPosition(Item[] array, Item item) {
    List<Item> arr = new ArrayList<Item>(Arrays.asList(array));
    return (int) IntStream.range(0, arr.indexOf(item)+1).filter(i -> item.name.equals(arr.get(i).name)).count();
}

Демо

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;

class Item {
    String name;

    public Item(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Item [name=" + name + "]";
    }
}

public class Main {
    public static void main(String[] args) {
        Item item0 = new Item("nameA");
        Item item1 = new Item("nameB");
        Item item2 = new Item("nameB");
        Item item3 = new Item("nameB");
        Item item4 = new Item("nameC");
        Item item5 = new Item("nameC");
        Item item6 = new Item("nameB");

        Item[] array = { item0, item1, item2, item3, item4, item5, item6 };
        System.out.println(countOfItemByNameAndPosition(array, item2));
        System.out.println(countOfItemByNameAndPosition(array, item6));
        System.out.println(countOfItemByNameAndPosition(array, item5));
    }

    public static int countOfItemByNameAndPosition(Item[] array, Item item) {
        List<Item> arr = new ArrayList<Item>(Arrays.asList(array));
        return (int) IntStream.range(0, arr.indexOf(item) + 1).filter(i -> item.name.equals(arr.get(i).name)).count();
    }
}

Вывод:

2
4
2

Не стесняйтесь комментировать в случай каких-либо сомнений / проблем.

1 голос
/ 31 марта 2020

Другой вариант - создать метод equals для вашего класса, который будет выглядеть как

public boolean equals(Object o) {
    if(!(o instanceof Item))
        return false;
    Item other = (Item)o;
    //you can change it to any compare method you want
    return other.name.equals(this.name);
}

А затем просто используйте функцию indexOf, и она будет использовать ваш метод для сравнения.

1 голос
/ 31 марта 2020

Да, есть. Во-первых, вы можете просто вернуть i, переменная cpt является избыточной. Во-вторых, вам не нужны две проверки внутри l oop. Вы можете комбинировать оба метода String#equals(String), который проверяет равенство двух строк. Вернуть -1, если имя не найдено. Отрицательные числа не являются допустимыми индексами массивов / коллекций, поэтому хорошие значения, чтобы сказать «не найден» .

public int positionOfSameName(ArrayList<Item> arr, Item item) {
    for (int i = 0; i < arr.size(); i++) {
        if (arr.get(i).name().equals(item.name()) {
            return i;
        }
    }
    return -1;
}

Редактировать: После вашего разъяснения что вы хотите посчитать вхождения данного имени в заданном массиве, вам нужно работать с дополнительной переменной.

public int positionOfSameName(ArrayList<Item> arr, Item item) {
    int counter = 0;
    for (int i = 0; i < arr.size(); i++) {
        if (arr.get(i).name().equals(item.name()) {
            counter++;
        }
    }
    return counter;
}

FYI: Вы должны рассмотреть вопрос об изменении имени метод. Как сейчас, он не делает то, что говорит по имени.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...