1. 程式人生 > >根據屬性名稱的字串,對集合按條件過濾

根據屬性名稱的字串,對集合按條件過濾

1. Java8裡面有根據物件屬性名稱,對集合進行過濾,如下:

過濾出doctId為1948的物件集合:

ret.setSchedulList(ret.getSchedulList().parallelStream().filter(g -> g.getDoctId().equals("1948")).collect(Collectors.toList()));

2. 當不知道物件為何物,只能用Object代替時,即需要有個通用的方法對集合按條件進行過濾時,可以這樣寫:

主要引用依賴:

        <!-- https://mvnrepository.com/artifact/commons-collections/commons-collections 
--> <dependency> <groupId>commons-collections</groupId> <artifactId>commons-collections</artifactId> <version>3.2.2</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils
--> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.9.3</version> </dependency>

程式碼實現:

Student類:

package cn.demo.pangu.lib;

import lombok.AllArgsConstructor;
import lombok.Data; @Data @AllArgsConstructor public class Student { private String stringType; private Integer integerType; private Long longType; @Override public String toString() { return "Student{" + "stringType='" + stringType + '\'' + ", integerType=" + integerType + ", longType=" + longType + '}'; } }

核心程式碼:

package cn.demo.pangu.lib.utils;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.PredicateUtils;

import java.math.BigDecimal;
import java.util.*;

@Data
@AllArgsConstructor
@Slf4j
public class FilterPredicate implements Predicate {

    private String property;
    private Object value;

    @Override
    public boolean evaluate(Object o) {
        try {
            Object beanValue;
            if (property.indexOf(".") > 0) {
                beanValue = PropertyUtils.getNestedProperty(o, property);
            } else {
                beanValue = PropertyUtils.getProperty(o, property);
            }
            if (beanValue == null) {
                return false;
            }
            if (!value.getClass().equals(beanValue.getClass())) {
                log.error("value.class != beanValue.class");
            }
            return compare(beanValue, value);
        } catch (Exception e) {
            log.error(e.getMessage() + "\n" + e.getCause());
        }
        return false;
    }

    private boolean compare(Object value, Object beanValue) {
        // FIXME: 還有其他的資料型別
        if (beanValue.getClass().equals(Integer.class)) {
            if (((Integer) beanValue).equals(value)) {
                return true;
            }
        }
        if (beanValue.getClass().equals(BigDecimal.class)) {
            if (((BigDecimal) beanValue).compareTo((BigDecimal) value) == 0) {
                return true;
            }
        }
        if (beanValue.getClass().equals(String.class)) {
            if (beanValue.toString().equals(value.toString())) {
                return true;
            }
        }
        if (beanValue.getClass().equals(Long.class)) {
            if ((beanValue.toString()).equals(value.toString())) {
                return true;
            }
        }
        return false;
    }

    private static Predicate setConditions(Map<String, Object> map) {
        List<Predicate> predicateList = new ArrayList<Predicate>();
        map.forEach((k, v) -> predicateList.add(new FilterPredicate(k, v)));
        return PredicateUtils.allPredicate(predicateList);
    }

    public static Collection select(Collection inputCollection, Map<String, Object> conditions) {
        return CollectionUtils.select(inputCollection, FilterPredicate.setConditions(conditions));
    }

    public static void select(Collection inputCollection, Map<String, Object> conditions, Collection outputCollection) {
        CollectionUtils.select(inputCollection, FilterPredicate.setConditions(conditions), outputCollection);
    }

    public static Collection selectRejected(Collection inputCollection, Map<String, Object> conditions) {
        return CollectionUtils.selectRejected(inputCollection, FilterPredicate.setConditions(conditions));
    }

    public static void selectRejected(Collection inputCollection, Map<String, Object> conditions, Collection outputCollection) {
        CollectionUtils.selectRejected(inputCollection, FilterPredicate.setConditions(conditions), outputCollection);
    }
}

測試用例:

package cn.demo.pangu.lib.utils;

import cn.demo.pangu.lib.Student;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.*;

@RunWith(SpringRunner.class)
public class FilterPredicateTest {

    List<Student> studentList = new ArrayList<>();
    List<LinkedHashMap> linkedHashMapList = new ArrayList<>();

    List<Student> result1 = new ArrayList<>();
    List<Student> result2 = new ArrayList<>();

    List<LinkedHashMap> result3 = new ArrayList<>();
    List<LinkedHashMap> result4 = new ArrayList<>();


    public void setList() {
        Student student1 = new Student("string", 1, 2L);
        Student student2 = new Student("string2", 2, 3L);
        Student student3 = new Student("string3", 1, 2L);
        Student student4 = new Student("string4", 1, 2L);
        studentList.add(student1);
        studentList.add(student2);
        studentList.add(student3);
        studentList.add(student4);

        result1.add(student1);

        result2.add(student2);
        result2.add(student3);
        result2.add(student4);
    }

    void setArrayList() {
        LinkedHashMap linkedHashMap = new LinkedHashMap();
        linkedHashMap.put("string1", "1");
        linkedHashMap.put("integer1", 1);
        linkedHashMap.put("long1", 1L);

        LinkedHashMap linkedHashMap2 = new LinkedHashMap();
        linkedHashMap2.put("string1", "2");
        linkedHashMap2.put("integer1", 2);
        linkedHashMap2.put("long1", 2L);

        LinkedHashMap linkedHashMap3 = new LinkedHashMap();
        linkedHashMap3.put("string1", "3");
        linkedHashMap3.put("integer1", 3);
        linkedHashMap3.put("long1", 3L);

        LinkedHashMap linkedHashMap4 = new LinkedHashMap();
        linkedHashMap4.put("string1", "4");
        linkedHashMap4.put("integer1", 4);
        linkedHashMap4.put("long1", 4L);

        linkedHashMapList.add(linkedHashMap);
        linkedHashMapList.add(linkedHashMap2);
        linkedHashMapList.add(linkedHashMap3);
        linkedHashMapList.add(linkedHashMap4);

        result3.add(linkedHashMap);

        result4.add(linkedHashMap2);
        result4.add(linkedHashMap3);
        result4.add(linkedHashMap4);
    }

    @Test
    public void testStudent() {
        setList();
        // 過濾條件
        Map<String, Object> map = new HashMap<>();
        map.putIfAbsent("stringType", "string");
        map.putIfAbsent("integerType", 1);
        map.putIfAbsent("longType", 2L);

        List<Student> students = (List<Student>) FilterPredicate.select(studentList, map);
        Assert.assertEquals(result1, students);
        List<Student> studentReject = (List<Student>) FilterPredicate.selectRejected(studentList, map);
        Assert.assertEquals(result2, studentReject);

        List<Student> list = new ArrayList<>();
        FilterPredicate.selectRejected(studentList, map, list);
        Assert.assertEquals(result2, list);
    }

    @Test
    public void testLinkedHashMap() {
        setArrayList();
        // 過濾條件
        Map<String, Object> map = new HashMap<>();
        map.putIfAbsent("string1", "1");
        map.putIfAbsent("integer1", 1);
        map.putIfAbsent("long1", 1L);

        List<LinkedHashMap> linkedHashMaps = (List<LinkedHashMap>) FilterPredicate.select(linkedHashMapList, map);
        Assert.assertEquals(result3, linkedHashMaps);

        List<LinkedHashMap> linkedHashMapRejecteds = (List<LinkedHashMap>) FilterPredicate.selectRejected(linkedHashMapList, map);
        Assert.assertEquals(result4, linkedHashMapRejecteds);
    }
}