【问题标题】:Simplest way to convert a list to a set based on a boolean property?将列表转换为基于布尔属性的集合的最简单方法?
【发布时间】:2012-07-04 17:11:17
【问题描述】:

我有一个对象列表,每个对象都有一个布尔“选定”属性。如果“selected”属性为真,我希望将它们放在一组中。除了通过将对象添加到集合中的 for 循环之外,还有其他方法可以实现吗?

【问题讨论】:

  • 你想从什么映射到什么?
  • 您可以获得一个库来为您执行循环和属性访问(Google Guava 可以做到),但这并没有真正使它有任何不同(或者代码更简洁)。跨度>
  • 您想要一套或一张地图?如果是map,key的值是多少?
  • @JigarJoshi:“地图”的意思是“集合”(他说了三分之一)。
  • 抱歉,我的意思是“设置”。提这个问题有点太快了。

标签: java list loops map


【解决方案1】:

对于这么简单的事情,只需编写一个循环并完成它。

如果这是您要反复实施的模式:

(未经测试,因此可能有一两个错字)

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 的实现知道如何检查对象并决定是否应该保留它们。

【讨论】:

  • 请注意,调用的类型并不比直接循环少……Java 8 将在这里带来帮助。
  • 还要注意每次需要使用此代码时如何创建一个新的 Selector 实例。此外,每次需要这种迭代时都会生成一个新类。因此 - 我真的建议使用简单的 for 循环。
  • 我不得不接受这样一个事实,即循环有时是最有效的方法。干杯,
【解决方案2】:

您可以使用任何功能性的 java 库。 例如,根据我使用 Lambdaj (http://code.google.com/p/lambdaj/) 的经验:

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

【讨论】:

    【解决方案3】:

    如果您使用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 循环。

    【讨论】:

    【解决方案4】:

    嗯,我想您正在寻找的是一种功能性方法。我建议您查看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")));
    

    【讨论】:

    • 为示例添加了一个小说明(lambdaj 示例是第二个示例)。
    猜你喜欢
    • 2010-10-11
    • 2011-04-23
    • 2011-02-07
    • 1970-01-01
    • 2010-12-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    相关资源
    最近更新 更多