Метод Java: Нахождение объекта в списке массива, учитывая известное значение атрибута

Я бы создал структуру stage, level и strings и получил бы массив этой структуры

struct StageLevel {
    let stage: Int
    let level: Int
    let words: [String]
}

let stageLevelArray: [StageLevel] = 
    [StageLevel(stage: 1, level: 1, words: ["Hello", "Hi"]), 
    StageLevel(stage: 1, level: 2, words: ["Red", "Blue", "Green"]), 
    StageLevel(stage: 2, level: 1, words: ["No", "Yes"])]

, тогда вы можете отфильтровать все элементы для выбранной стадии

let levels = stageLevelArray.filter( { [111].stage == 1} )
[116 ] или отфильтруйте для стадии и уровня

let selection = stageLevelArray.filter( { [112].stage == 1 && [112].level == 2 } )

или если вам нужны только уровни или массивы

let levels = stageLevelArray.filter( { [113].stage == 1} ).map { [113].level}
let selection = stageLevelArray.filter( { [113].stage == 1 && [113].level == 2 } ).map { [113].words }
21
задан Northener 10 April 2009 в 23:54
поделиться

5 ответов

A , в то время как применяется к выражению или блоку после , тогда как .

У вас нет блока, поэтому ваш while заканчивается с выражением dog = al.get (i);

while(dog.getId()!=id && i<length)
                dog=al.get(i);

Все, что после этого происходит только один раз.

Нет смысла обновлять собаку, так как вы никогда не используете собаку, которую вы новичок ; Вы немедленно назначаете Dog из массива для ссылки на вашу собаку.

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

Редактировать: это было не задано, почему ??

Комментарий от ОП:

Еще один вопрос относительно того, чтобы не создавать новый экземпляр собаки. Если я просто вынимаю копии объектов из списка массивов, как я могу затем вынуть их из списка массивов, не имея объекта, в который я их помещаю? Я также заметил, что я не заключал в скобки цикл while.

Ссылка на Java и объект, на который она ссылается, это разные вещи. Они очень похожи на ссылку и объект C ++, хотя ссылка на Java может быть перенаправлена ​​как указатель на C ++.

В результате получается, что Dog dog; или Dog dog = null дает вам ссылку, которая не указывает ни на один объект. new Dog () создает объект, на который можно указать.

После этого с dog = al.get (i) означает, что ссылка теперь указывает на ссылка на собаку, возвращенная al.get (i) . Поймите, в Java объекты никогда не возвращаются, только ссылки на объекты (которые являются адресами объекта в памяти).

Указатель / ссылка / адрес собаки, которую вы обновили, теперь утерян, так как ни один код не ссылается на него, так как референт был заменен референтом, который вы получили из al.get () . В конце концов Java-сборщик мусора уничтожит этот объект; в C ++ вы бы «вытекли» из памяти.

В результате вам нужно создать переменную, которая может ссылаться на Dog; вам не нужно создавать собаку с new .

(По правде говоря, вам не нужно создавать ссылку, поскольку то, что вам действительно нужно делать, это возвращать то, что Map возвращает из своей функции get (). Если Map не параметризована для Dog, например, так: Карта , тогда вам нужно разыграть возврат из get, но вам не понадобится ссылка: return (Dog) map.get (id); или, если карта параметризована, return map.get (id) . И эта одна строка - ваша целая функция, и в большинстве случаев она будет быстрее, чем итерация массива.)

16
ответ дан 29 November 2019 в 06:11
поделиться

Чтобы повысить производительность операции, если вы всегда хотите искать объекты по некоторому уникальному идентификатору, тогда вы можете рассмотреть возможность использования карты . Это обеспечит постоянный поиск по ключу. Вы по-прежнему можете перебирать сами объекты, используя map values ​​() .

Быстрый фрагмент кода, с которого можно начать:

// Populate the map
Map<Integer,Dog> dogs = new HashMap<Integer,Dog>();
for( Dog dog : /* dog source */ ) {
    dogs.put( dog.getId(), dog );
}

// Perform a lookup
Dog dog = dogs.get( id );

Это поможет немного ускорить процесс, если вы выполняете несколько поиски той же природы в списке. Если вы просто выполняете один поиск, то независимо от этого вы будете подвергаться одному и тому же циклу.

16
ответ дан 29 November 2019 в 06:11
поделиться

Вы должны пройти через весь массив, это не изменить. Однако вы можете сделать это немного проще

for (Dog dog : list) {
  if (dog.getId() == id) {
    return dog; //gotcha!
  }
}
return null; // dog not found.

или без нового цикла for

for (int i = 0; i < list.size(); i++) {
  if (list.get(i).getId() == id) {
    return list.get(i);
  }
}
13
ответ дан 29 November 2019 в 06:11
поделиться

Мне было интересно узнать, что в оригинальном постере использовался стиль что избежало ранних выходов. Однократная; Single Exit (SESE) - интересный стиль, который я на самом деле не исследовал. Уже поздно, и у меня есть бутылка сидра, поэтому я написал решение (не тестировалось) без досрочного выхода.

Я должен был использовать итератор. К сожалению, java.util.Iterator имеет побочный эффект в методе get. (Мне не нравится дизайн Iterator из-за разветвлений его исключений.)

private Dog findDog(int id) {
    int i = 0;
    for (; i!=dogs.length() && dogs.get(i).getID()!=id; ++i) {
        ;
    }

    return i!=dogs.length() ? dogs.get(i) : null;
}

Обратите внимание на дублирование выражения i! = Dogs.length () (возможно, выбрал dogs.get (я) .getID ()! = идентификатор ).

1
ответ дан 29 November 2019 в 06:11
поделиться

Скажите коллегам, что их Perl слишком похож на шум в линии. Пожалуйста, не запутывайте ваш код только для того, чтобы запутать его - это чистые цели разработки, которые дают Perl такую ​​плохую репутацию нечитабельности, когда действительно плохие программисты (видимо, ваши коллеги) пишут неаккуратный код. Хорошо структурированный, отступ и логический код - это хорошо. С - хорошая вещь.

Серьезно, хотя - лучшее место, чтобы выяснить, как писать на Perl, - это O'Reilly "Perl Best Practices" Дамиана Конвея. Он говорит вам, как он думает, что вы должны что-то делать, и он всегда дает веские основания для своей позиции, а также иногда дает веские основания не соглашаться. Я не согласен с ним по некоторым вопросам, но его аргументация обоснована. Вероятность того, что вы работаете с кем-либо, кто знает Perl лучше, чем мистер Конвей, довольно мала, и наличие печатной книги (или, по крайней мере, подписки на Safari) дает вам более надежную поддержку для ваших аргументов. Возьмите копию Perl Cookbook, пока смотрите ее, так как рассмотрение примеров кода для решения типичных проблем должно помочь вам в правильном направлении. Я не хочу говорить «купи книгу», но это исключительно хорошие книги, которые должен прочитать любой разработчик Perl.

Что касается вашего конкретного кода, вы используете foreach, $ _ , расщепление без паренов, сдвигов и т. Д. Это выглядит довольно нелепо для моих глаз, которые развивались с Perl уже довольно давно. Одно замечание - я ненавижу английский модуль. Если вы должны его использовать, сделайте это, как , используйте английский qw (-no_match_vars); . Мы правильно написали метод равенства для Dog, который сравнивает на основе идентификатора Dog самый простой и простой способ вернуть элемент в списке:

if (dogList.contains(dog)) {
   return dogList.get(dogList.indexOf(dog));
}

Это менее интенсивно, чем другие подходы. Вам не нужен цикл вообще в этом случае. Надеюсь, что это поможет.

PS Вы можете использовать Apache Commons Lang для написания простого метода равенства для Dog следующим образом:

@Override
public boolean equals(Object obj) {     
   EqualsBuilder builder = new EqualsBuilder().append(this.getId(), obj.getId());               
   return builder.isEquals();
}
44
ответ дан 29 November 2019 в 06:11
поделиться
Другие вопросы по тегам:

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