2012-07-04 3 views
2

У меня есть список объектов, каждый из которых имеет логическое свойство «selected». Я хочу, чтобы они были в наборе, если свойство «selected» имеет значение true. За исключением цикла for через объекты, добавляющие каждый в набор, есть ли другой способ достичь этого?Простейший способ преобразования списка в набор на основе логического свойства?

+2

И вы хотите отобразить, с чего на что? –

+2

Вы можете получить библиотеку для выполнения циклов и доступа к свойствам для вас (Google Guava может это сделать), но это не делает его другим (или гораздо более кратким для кода). – Thilo

+0

Вы хотите иметь набор или карту? Если map, каково значение ключа? – dbf

ответ

2

Для чего-то это просто написать цикл и сделать с ним.

Если это шаблон, который вы собираетесь осуществить снова и снова:

(непроверенная, так что может быть опечатка или два)

public interface Selector<T> { 
    public boolean select(T t); } 

public <T> Set<T> grep(Collection<T> coll, Selector<T> sel) { 
    Set<T> result = new Set<T>; 
    for (T item : coll) 
     if (sel.select(T)) 
      result.add(T); 
    return result; 
} 

И призывание

List<SomeClasss> input = ...; 
Set<SomeClass> output = grep(
    input, 
    new Selector<SomeClass> { 
     public boolean select(SomeClass item) { 
      return some-boolean-function-of-item; // decide which items to keep here 
     } 
    } 
); 

Реализации Selector знают, как исследовать объекты и решать, следует ли их хранить.

+0

Обратите внимание на то, что вызов не менее типу, чем прямой цикл ... Java 8 принесет вам помощь. – Thilo

+0

Также обратите внимание, как каждый раз, когда вам нужно использовать этот код, создается новый экземпляр селектора. Более того, новый класс создается для каждого раза, когда вам нужна такая итерация. Поэтому - я бы действительно советовал использовать простой цикл 'for'. – bezmax

+0

Я просто должен согласиться с тем, что петли иногда являются наиболее эффективным методом. Cheers, – edwardmlyte

1

Для этого вы можете использовать любую функциональную библиотеку java. Например, из моего опыта с Lambdaj (http://code.google.com/p/lambdaj/):

Set<Entity> entitiesSet = new HashSet<Entity>(filter(having(on(Entity.class).getSelected(), equalTo(true)), entities)); 
1

Hm, я предполагаю, что вы ищете является функциональным подходом. Я бы порекомендовал взглянуть либо на lamdaj (если вы хотите придерживаться Java и вам нужен только API) или Scala (если вам нужен более богатый набор функций).

Пример

Императив версия:

List<Sale> salesOfAFerrari = new ArrayList<Sale>(); 
for (Sale sale : sales) { 
    if (sale.getCar().getBrand().equals("Ferrari")) 
     salesOfAFerrari.add(sale); 
} 

Вы можете сделать это в одной строке с lambdaj:

List<Sale> salesOfAFerrari = select(sales, 
    having(on(Sale.class).getCar().getBrand(),equalTo("Ferrari"))); 
+0

Добавил небольшое пояснение к примеру (пример lambdaj был вторым). – rlegendi

1

если вы использовали java 8 вы могли бы сделать это:

List<MyObject> myList = Arrays.asList(a,b,c,d); 

Set<MyObject> mySet = myList 
     .filter(e -> e.getMyBool()) 
     .into(new Set<MyObject>()); 

Предполагая, что a - d - это всего лишь экземпляры вашего объекта с булевым свойством. Но java 8 еще не вышел, поэтому я бы просто использовал цикл for.

+0

Re; сборник литералов: http://stackoverflow.com/questions/2700775/why-collection-literals Действительно ли это сделать разрез для 7 или 8? – Thilo

+1

@ Тило Я так не думаю о 7 – NimChimpsky

Смежные вопросы