2015-08-23 17 views
5

Tôi có bản đồ sau của tiêu chí tìm kiếm:thông số Pass để các vị từ

private final Map<String, Predicate> searchMap = new HashMap<>(); 

private void initSearchMap() { 
    Predicate<Person> allDrivers = p -> p.getAge() >= 16; 
    Predicate<Person> allDraftees = p -> p.getAge() >= 18 
      && p.getAge() <= 25 
      && p.getGender() == Gender.MALE; 
    Predicate<Person> allPilots = p -> p.getAge() >= 23 
      && p.getAge() <=65; 

    searchMap.put("allDrivers", allDrivers); 
    searchMap.put("allDraftees", allDraftees); 
    searchMap.put("allPilots", allPilots); 
} 

Tôi đang sử dụng bản đồ này theo cách sau:

pl.stream() 
    .filter(search.getCriteria("allPilots")) 
    .forEach(p -> { 
     p.printl(p.getPrintStyle("westernNameAgePhone")); 
    }); 

Tôi muốn biết, làm thế nào tôi có thể chuyển một số tham số vào bản đồ các vị từ?

I.e. Tôi muốn lấy vị ngữ từ bản đồ bằng chữ viết tắt của chuỗi và chèn một tham số vào phần được lấy ra từ một vị từ bản đồ.

pl.stream() 
    .filter(search.getCriteria("allPilots",45, 56)) 
    .forEach(p -> { 
     p.printl(p.getPrintStyle("westernNameAgePhone")); 
    }); 

Đây là link từ Tôi đã giải quyết được cách tiếp cận bản đồ vị ngữ này.

+1

Những gì bạn muốn làm sẽ không biên dịch, và bạn không giải thích nó phải làm gì. –

+0

Tôi vừa đưa ra một ví dụ. Chắc chắn, nó sẽ không biên dịch. Đây là những gì tôi muốn làm: Tôi muốn có được một vị từ một bản đồ bằng cách viết tắt chuỗi của nó và chèn một tham số vào đưa ra từ một vị từ bản đồ. –

+1

Thông số sẽ được sử dụng để làm gì? Mục tiêu của 45 trong ví dụ của bạn là gì? –

Trả lời

4

Dường như những gì bạn muốn không lưu trữ vị từ trong Bản đồ. Những gì bạn muốn là để có thể lưu trữ một cái gì đó trong một bản đồ có thể tạo ra một Predicate<Person> từ một tham số int. Vì vậy, những gì bạn muốn là một cái gì đó như thế này:

Map<String, IntFunction<Predicate<Person>>> searchMap = new HashMap<>(); 

Bạn sẽ lấp đầy nó như vậy:

searchMap.put("allPilots", maxAge -> 
    (p -> p.getAge() >= 23 
    && p.getAge() <= maxAge)); 

Và bạn woult sử dụng nó như thế này:

Predicate<Person> allPilotsAgedLessThan45 = 
    searchMap.get("allPilots").apply(45); 

Tất nhiên, điều đó sẽ rõ ràng hơn nếu bạn đã tạo giao diện chức năng của riêng mình:

@FunctionalInterface 
public MaxAgePersonPredicateFactory { 
    Predicate<Person> limitToMaxAge(int maxAge); 
} 

Bạn vẫn sẽ lấp đầy bản đồ cùng một cách, nhưng sau đó bạn sẽ có mã hơi redable hơn khi sử dụng nó:

Predicate<Person> allPilotsAgedLessThan45 = 
    searchMap.get("allPilots").limitToMaxAge(45); 
+0

Chính xác những gì tôi đang tìm kiếm. Cảm ơn bạn! –

+1

Cho rằng OP muốn truyền vào hai tham số int, đây có phải là một hàm số sinh > thay vì IntFunction không? – KumarM

+0

@KumarM Tôi bỏ lỡ tham số thứ hai trong câu hỏi và chỉ nhận thấy số 45. Nhưng có, nếu anh ta cần hai tham số, chữ ký của nhà máy sẽ phải thay đổi. –

1

Theo tôi được biết, những gì bạn muốn làm là ghi đè lên một số thông số trong một tên Predicate , nhưng tôi nghĩ điều này sẽ dẫn đến sự nhầm lẫn. Nếu tôi hỏi vị ngữ xác định xem ai đó có đủ điều kiện để trở thành phi công hay không, tôi không muốn phải lo lắng về việc biết yêu cầu là gì vào thời điểm tôi gọi nó.

vị Tạo on the fly sử dụng một Map sẽ được khôn lanh - Tôi nghĩ cách đẹp nhất sẽ được thay có một Map<String, PredicateFactory>, nơi PredicateFactory là một số loại lớp phức tạp mà tạo ra vị đưa ra một số thông số:

Map<String, PredicateFactory<T>> predicates = new HashMap<>(); 

public Predicate<T> get(String name, Object... params) { 
    return predicates.get(name).apply(params); 
} 

để tâm trí của tôi, cách tốt hơn để tạo ra "năng động" vị là với các phương pháp tĩnh:

public class PredicatesQuestion { 

    public static void main(String[] args) { 
     List<Person> people = Arrays.asList(new Person(20, Gender.MALE), 
       new Person(45, Gender.FEMALE), new Person(50, Gender.MALE), 
       new Person(65, Gender.MALE)); 

     people.stream() 
       .filter(personIsBetweenAges(16, 25)) 
       .forEach(person -> { 
        System.out.println(person.getAge() + ", " + person.getGender()); 
       }); 
    } 

    private static Predicate<Person> personIsMale() { 
     return person -> person.getGender() == Gender.MALE; 
    } 

    private static Predicate<Person> personIsBetweenAges(int lower, int upper) { 
     return personIsAtLeast(lower).and(personIsYoungerThan(upper)); 
    } 

    private static Predicate<Person> personIsAtLeast(int age) { 
     return person -> person.getAge() >= age; 
    } 

    private static Predicate<Person> personIsYoungerThan(int age) { 
     return person -> person.getAge() < age; 
    } 
} 

Đó là sau đó tầm thường để tạo ra các vị từ mô tả theo yêu cầu:

private static Predicate<Person> personIsOfDrivingAge() { 
    return personIsAtLeast(17); 
} 

private static Predicate<Person> couldBePilot() { 
    return personIsBetweenAges(23, 65).and(personIsMale()); 

} 

Và các loại điều bạn đang cố gắng để đạt được với một số thông số trọng vẫn còn rõ ràng với một chút thành phần:

people.stream() 
     .filter(couldBePilot().and(personIsBetweenAges(45, 56))) 
     .forEach(person -> { 
      System.out.println(person.getAge() + ", " + person.getGender()); 
     }); 
Các vấn đề liên quan