2012-03-28 35 views
2

我有一系列的屬性,要麼是或者不是的,應用到我的對象關聯:Java的屬性與邏輯介詞

EVEN 
ODD 
POSITIVE 
NEGATIVE 
NEGATIVE_AND_ODD 

和他們每個人的適用對象當且僅當一些邏輯語句成立,即

EVEN iff num%2==0 
ODD iff num%2!=0 
POSITIVE iff num>0 
NEGATIVE iff num<0 
NEGATIVE_AND_ODD iff num < 0 and num%2==0 

我有大量的這些屬性和新的屬性可以在任何時候添加。屬性彼此沒有依賴關係,也不應該創建這種依賴關係。

我需要一個方案,以便我的主類可以這樣做:

Go through the list of attributes 
    If this attribute fits its required logical predicate, then 
    add the attribute to my object 

你會用什麼樣的工具呢?

+0

什麼'新屬性可以隨時添加.'是什麼意思?它們可以在程序運行時添加嗎?謂詞是如何定義的? 「 – 2012-03-28 01:53:48

+0

」可以隨時添加新的屬性「只意味着我不應該期望這個列表保持靜態。它們將被正常添加到該程序中。謂詞由業務邏輯定義,並且謂詞和屬性之間沒有真正的「漂亮」連接。 – Jeremy 2012-03-28 01:55:33

+0

但是,謂詞表達是如何表達的?它們與「iff num%2 == 0」是否完全相同,即在某種語言中,您需要解析和評估謂詞? – 2012-03-28 01:58:55

回答

1

你可以嘗試這樣的事情

interface Attribute 
{ 
     public boolean matches(boolean someBoolean, int num); 
} 

,然後實現每個屬性像

class Even implements Attribute 
{ 
    public boolean matches(boolean someBoolean, int num) 
    { 
     // someBoolean is not important to this attribute 
     // but it may be in others 
     return num%2==0; 
    } 
} 

然後,你可以只是做的Attribute數組(或列表或其他),並遍歷他們。

1

下面是一個方法:

  • 與單個方法boolean check(int num);
  • 爲每個屬性的類創建接口Attribute,實施檢查()方法來執行每個屬性的檢查。如果你想保存輸入,你可以使用匿名內部類。
  • 每個屬性

的一個實例創建一個列表,則你幾乎可以直接實現你的算法:剛過屬性循環,並呼籲檢查爲每一個適當的值。

1

A Predicate是一個布爾值函數,給定一個輸入測試屬性是真還是假。謂詞也稱爲屬性的同義詞。

我首先定義一個Predicate接口。

public abstract class Predicate<T> { 
    public abstract boolean eval(T t); 
    public Predicate<T> and(Predicate<? super T> p) {...}; 
    public Predicate<T> and(Predicate<? super T> ... p) {...}; 
    public Predicate<T> negate() {...}; 
    public Predicate<T> or(Predicate<? super T> p) {...}; 
    public Predicate<T> or(Predicate<? super T> ... p) {...}; 
    public Predicate<T> xor(Predicate<? super T> p) {...}; 
    public Predicate<T> xor(Predicate<? super T> ... p) {...}; 
} 

然後,你可以定義每個屬性:

public static final Predicate<Integer> EVEN = new Predicate<Integer>(){ 
    public boolean eval(Integer n) { 
     return n % 2 == 0; 
    } 
}; 

假設要篩選一組基於其特性的整數,那麼我會假設你必須定義一個過濾方法(其對應於古典high-order function過濾在給定的謂詞項):

public static <T> List<T> filter(List<? extends T> items, 
           Predicate<? super T> predicate) { 
    List<T> result = new ArrayList<T>(); 
    for(T item : items){ 
     if(predicate.eval(item)){ 
      result.add(item); 
     } 
    } 
    return result; 
} 

讓我們看看這種過濾在操作的一個例子:

List<Integer> myNumbers = asList(-5,-4,-3,-2,-1,0,1,2,3,4,5); 
List<Integer> onlyEven = filter(myNumbers, EVEN); 
List<Integer> positiveAndEven = filter(myNumbers, POSITIVE.and(EVEN)); 

好這個做法是,一旦JDK 8釋放所有這些功能將由語言通過使用lambda expressions提供。

最終,你將取代你的屬性定義lambda表達式:

public static final Predicate<Integer> EVEN = n -> n % 2 == 0; 
public static final Predicate<Integer> ODD = n -> n % 2 != 0; 
public static final Predicate<Integer> POSITIVE = n -> n > 0; 
public static final Predicate<Integer> NEGATIVE = n -> n < 0; 

你過濾將提供內置在你的收藏,讓你簡單地做:

List<Integer> myNumbers = asList(-5,-4,-3,-2,-1,0,1,2,3,4,5); 
List<Integer> onlyEven = myNumbers.filter(EVEN).into(new ArrayList<Integer>()); 
List<Integer> positiveEven = myNumbers.filter(POSITIVE.and(EVEN)).into(new ArrayList<Integer>()); 
List<Integer> positiveOrOdd = myNumbers.filter(POSITIVE.or(ODD)).into(new ArrayList<Integer>()); 

的謂詞接口將成爲JDK 8 java.util.functions包的一部分。所以,最終你將能夠拋棄你的並使用JDK中內置的一個。