У меня есть несколько объектов результатов поиска, как указано ниже:
public class TradeSearchResult{
private String tradeRefNo;
private String relatedTradeId;
private String custodyDate;
private String orderNumber;
private String odrQty;
private String price : 500;
}
public class CollateralTradesSearchResult{
private String excludeTradeOUT;
private String settlementStatus;
private String fundId;
private String altFundId;
private String apNumber;
private String collateralOrderNumber;
private String componenetIdentifier;
}
Теперь у меня есть объект Критерии фильтра поиска
public class CRITERION {
protected String field; //The field denotes any field name of the either
SearchResult object
protected String operator; its will be EQUALS or NOT_EQUALS
protected String value; Value of the field.
}
Теперь мне нужно написать метод динамического фильтра, гдеЯ передам объект List of Criterion и могу передать List либо SearchResult, как показано ниже
public static List<Object> applyFilter(List<CRITERION> comp, List<?> objectList){
//The CRITERION.fiedName can be same in more than one in the list
return filteredList;
}
, вот один пример: рассмотрим приведенный ниже список
TradeSearchResult{
tradeRefNo : W12343;
relatedTradeId: N993093;
custodyDate : 2018-12-14;
orderNumber : 0000342343;
String odrQty : 12;
String price : 500;
},
{
tradeRefNo : W12344;
relatedTradeId: N993093;
custodyDate : 2018-12-14;
orderNumber : 0000342344;
String odrQty : 18;
String price : 600;
},
{
tradeRefNo : W12345;
relatedTradeId: N993094;
custodyDate : 2018-12-14;
orderNumber : 0000342345;
String odrQty : 20;
String price : 700;
}
Now the Criterion class is like
CRITERION{
field :relatedTradeId;
operator : EQUALS;
value :N993093;
}
{
field :relatedTradeId;
operator : EQUALS;
value :N993094;
}
{
field :orderNumber ;
operator : EQUALS;
value :0000342344;
}
Он вернет только одинрезультат даже relatedTradeId имеет два фильтра
TradeSearchResult{
tradeRefNo : W12344;
relatedTradeId: N993093;
custodyDate : 2018-12-14;
orderNumber : 0000342344;
String odrQty : 18;
String price : 600;
}
Теперь одним и тем же методом applyFIlter я могу отправить список Criterion и список ColatellTradesSearchResult и вернуть отфильтрованный результат.Вот то, что я попробовал
public static List<Object> applyFilter(List<CRITERION> criList, List<?> objectList){
long startTime = Calendar.getInstance().getTimeInMillis();
Set<Object> objectSet = new HashSet<>();
for(CRITERION cri : criList){
String fieldName = cri.getFIELD();
objectList.stream().filter(p->beanProperties(p).get(fieldName).equals(cri.getVALUE())).forEachOrdered(objectSet::add);
//objectList.retainAll(objectSet);
//objectSet.clear();
}
List<Object> ret = new ArrayList<>(objectSet);
long endTime = Calendar.getInstance().getTimeInMillis();
System.out.println("Size"+ ret.size());
System.out.println("Time Taken to Search"+ String.valueOf(endTime-startTime));
return ret;
}
Вот метод beanProperties ()
public static Map<String, Object> beanProperties(Object bean) {
try {
Map<String, Object> map = new HashMap<>();
Arrays.asList(Introspector.getBeanInfo(bean.getClass(), Object.class)
.getPropertyDescriptors())
.stream()
// filter out properties with setters only
.filter(pd -> Objects.nonNull(pd.getReadMethod()))
.forEach(pd -> { // invoke method to get value
try {
Object value = pd.getReadMethod().invoke(bean);
if (value != null) {
map.put(pd.getName(), value);
}
} catch (Exception e) {
// add proper error handling here
}
});
return map;
} catch (IntrospectionException e) {
// and here, too
return Collections.emptyMap();
}
}
Any help using Stream or by any means will be helpful.