1

ExpressionParserSpring には、 (コレクションの選択)を介してコレクションのサブセットを返す機能があります。

たとえば、単純なクラスを想像してください。

public Customer {
  private String name;
  private boolean vip;
  private boolean conferenceAttendee;
}

以前に変数として設定されたList<Customer>コレクションがある場合: 「選択式」を使用して、vip が true であるすべての顧客のサブセットを取得できます。StandardEvaluationContextevalContext.setVariable("customerList", customers);<variable>.?[<selectionExpression>]

List<Customer> vipCustomers = 
       (List<Customer>)new SpelExpressionParser()
            .parseExpression("#customerList.?[vip]")
            .getValue(evalContext);

evalContext.setVariable("customerList", vipCustomers)中間リスト を呼び出して 2 番目の parseExpression を実行することなく、ユニオン (vip || conferenceAttendee) または交差 (vip && conferenceAttendee) として選択式でこの同じロジックを実行することは可能ですか?

これに似たもの:

// This doesn't work...
List<Customer> vipCustomers = 
       (List<Customer>)new SpelExpressionParser()
            .parseExpression("#customerList.?[vip || conferenceAttendee]")
            .getValue(evalContext);

他の同等のソリューションとは対照的に、SpelExpressionParser の parseExpression に渡すことができる有効な選択式を具体的に理解しようとしています。

4

1 に答える 1

3

あなたはとても親密です。Spring Expression Language には、使用できるOR および AND 論理演算子があります。

    customerList.add(new Customer("jim", true, false));
    customerList.add(new Customer("bob", false, true));
    customerList.add(new Customer("rob", true, true));

    List<Customer> vipCustomers =
            (List<Customer>)new SpelExpressionParser()
                    .parseExpression("#customerList.?[vip]")
                    .getValue(evalContext);
    System.out.println(vipCustomers);
    //[Customer{name='jim'}, Customer{name='rob'}]

    List<Customer> vipANDConfAttendeesCustomers =
            (List<Customer>)new SpelExpressionParser()
                    .parseExpression("#customerList.?[vip and conferenceAttendee]")
                    .getValue(evalContext);
    System.out.println(vipANDConfAttendeesCustomers);
    //[Customer{name='rob'}]        

    List<Customer> vipORConfAttendeesCustomers =
            (List<Customer>)new SpelExpressionParser()
                    .parseExpression("#customerList.?[vip or conferenceAttendee]")
                    .getValue(evalContext);
    System.out.println(vipORConfAttendeesCustomers);
    //[Customer{name='jim'}, Customer{name='bob'}, Customer{name='rob'}]        

編集前 - 実際の回答ではなく提案として無視できます

Spring を使用しない別のアプローチを紹介させてください。これは、より機能的な感覚を持ち、適切にスケーリングして、複雑な相互作用や相互作用の表現力を向上させます。次のソリューションでは、Guava の Predicatesを使用して、クエリのニーズの主要なビルディング ブロックを表現しています。

    Predicate<Customer> isVip = new Predicate<Customer>() {
        @Override
        public boolean apply(Customer customer) {
            return customer.isVip();
        }
    };

    Predicate<Customer> isConferenceAttendee = new Predicate<Customer>() {
        @Override
        public boolean apply(Customer customer) {
            return customer.isConferenceAttendee();
        }
    };

次に、それらをPredicates.andPredicates.orを含むより複雑なクエリに結合し、Iterables.filterを使用して Collection をフィルター処理します (それらを反復する機能的な方法)。

Iterables.filter(customers, isVip);
Iterables.filter(customers, Predicates.and(isVip,isConferenceAttendee));
Iterables.filter(customers, Predicates.or(isVip,isConferenceAttendee));

名前が顧客を一意に識別するものであるという仮定に基づいて、自動生成された equals/hashcode/toString メソッドを使用した完全な動作例:

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;

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

public class GuavaTest {

    public static void main(String ...args){

        Predicate<Customer> isVip = new Predicate<Customer>() {
            @Override
            public boolean apply(Customer customer) {
                return customer.isVip();
            }
        };

        Predicate<Customer> isConferenceAttendee = new Predicate<Customer>() {
            @Override
            public boolean apply(Customer customer) {
                return customer.isConferenceAttendee();
            }
        };

        List<Customer> customers = Lists.newArrayList();

        customers.add(new Customer("jim",true,false));
        customers.add(new Customer("bob",false,true));
        customers.add(new Customer("rob",true,true));

        System.out.println("Vips:\t"+Iterables.filter(customers, isVip));
        System.out.println("Vips && ConfAttendees:\t"+Iterables.filter(customers, Predicates.and(isVip,isConferenceAttendee)));
        System.out.print("Vips || ConfAttendees:\t"+Iterables.filter(customers, Predicates.or(isVip,isConferenceAttendee)));
    }
}

class Customer {
 private String name;
 private boolean vip;
 private boolean conferenceAttendee;

    Customer(String name, boolean vip, boolean conferenceAttendee) {
        this.name = name;
        this.vip = vip;
        this.conferenceAttendee = conferenceAttendee;
    }

    public String getName() {
        return name;
    }

    public boolean isVip() {
        return vip;
    }

    public boolean isConferenceAttendee() {
        return conferenceAttendee;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Customer customer = (Customer) o;

        if (name != null ? !name.equals(customer.name) : customer.name != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return name != null ? name.hashCode() : 0;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "name='" + name + '\'' +
                '}';
    }
}
于 2012-11-15T00:20:26.767 に答える