What is the best way to filter a Java Collection?

后端 未结 27 3374
故里飘歌
故里飘歌 2020-11-21 06:55

I want to filter a java.util.Collection based on a predicate.

相关标签:
27条回答
  • 2020-11-21 07:30

    Using java 8, specifically lambda expression, you can do it simply like the below example:

    myProducts.stream().filter(prod -> prod.price>10).collect(Collectors.toList())
    

    where for each product inside myProducts collection, if prod.price>10, then add this product to the new filtered list.

    0 讨论(0)
  • 2020-11-21 07:31

    https://code.google.com/p/joquery/

    Supports different possibilities,

    Given collection,

    Collection<Dto> testList = new ArrayList<>();
    

    of type,

    class Dto
    {
        private int id;
        private String text;
    
        public int getId()
        {
            return id;
        }
    
        public int getText()
        {
            return text;
        }
    }
    

    Filter

    Java 7

    Filter<Dto> query = CQ.<Dto>filter(testList)
        .where()
        .property("id").eq().value(1);
    Collection<Dto> filtered = query.list();
    

    Java 8

    Filter<Dto> query = CQ.<Dto>filter(testList)
        .where()
        .property(Dto::getId)
        .eq().value(1);
    Collection<Dto> filtered = query.list();
    

    Also,

    Filter<Dto> query = CQ.<Dto>filter()
            .from(testList)
            .where()
            .property(Dto::getId).between().value(1).value(2)
            .and()
            .property(Dto::grtText).in().value(new string[]{"a","b"});
    

    Sorting (also available for the Java 7)

    Filter<Dto> query = CQ.<Dto>filter(testList)
            .orderBy()
            .property(Dto::getId)
            .property(Dto::getName)
        Collection<Dto> sorted = query.list();
    

    Grouping (also available for the Java 7)

    GroupQuery<Integer,Dto> query = CQ.<Dto,Dto>query(testList)
            .group()
            .groupBy(Dto::getId)
        Collection<Grouping<Integer,Dto>> grouped = query.list();
    

    Joins (also available for the Java 7)

    Given,

    class LeftDto
    {
        private int id;
        private String text;
    
        public int getId()
        {
            return id;
        }
    
        public int getText()
        {
            return text;
        }
    }
    
    class RightDto
    {
        private int id;
        private int leftId;
        private String text;
    
        public int getId()
        {
            return id;
        }
    
        public int getLeftId()
            {
                return leftId;
            }
    
        public int getText()
        {
            return text;
        }
    }
    
    class JoinedDto
    {
        private int leftId;
        private int rightId;
        private String text;
    
        public JoinedDto(int leftId,int rightId,String text)
        {
            this.leftId = leftId;
            this.rightId = rightId;
            this.text = text;
        }
    
        public int getLeftId()
        {
            return leftId;
        }
    
        public int getRightId()
            {
                return rightId;
            }
    
        public int getText()
        {
            return text;
        }
    }
    
    Collection<LeftDto> leftList = new ArrayList<>();
    
    Collection<RightDto> rightList = new ArrayList<>();
    

    Can be Joined like,

    Collection<JoinedDto> results = CQ.<LeftDto, LeftDto>query().from(leftList)
                    .<RightDto, JoinedDto>innerJoin(CQ.<RightDto, RightDto>query().from(rightList))
                    .on(LeftFyo::getId, RightDto::getLeftId)
                    .transformDirect(selection ->  new JoinedDto(selection.getLeft().getText()
                                                         , selection.getLeft().getId()
                                                         , selection.getRight().getId())
                                     )
                    .list();
    

    Expressions

    Filter<Dto> query = CQ.<Dto>filter()
        .from(testList)
        .where()
        .exec(s -> s.getId() + 1).eq().value(2);
    
    0 讨论(0)
  • 2020-11-21 07:33

    Since the early release of Java 8, you could try something like:

    Collection<T> collection = ...;
    Stream<T> stream = collection.stream().filter(...);
    

    For example, if you had a list of integers and you wanted to filter the numbers that are > 10 and then print out those numbers to the console, you could do something like:

    List<Integer> numbers = Arrays.asList(12, 74, 5, 8, 16);
    numbers.stream().filter(n -> n > 10).forEach(System.out::println);
    
    0 讨论(0)
  • 2020-11-21 07:33

    Are you sure you want to filter the Collection itself, rather than an iterator?

    see org.apache.commons.collections.iterators.FilterIterator

    or using version 4 of apache commons org.apache.commons.collections4.iterators.FilterIterator

    0 讨论(0)
  • 2020-11-21 07:33

    JFilter http://code.google.com/p/jfilter/ is best suited for your requirement.

    JFilter is a simple and high performance open source library to query collection of Java beans.

    Key features

    • Support of collection (java.util.Collection, java.util.Map and Array) properties.
    • Support of collection inside collection of any depth.
    • Support of inner queries.
    • Support of parameterized queries.
    • Can filter 1 million records in few 100 ms.
    • Filter ( query) is given in simple json format, it is like Mangodb queries. Following are some examples.
    • { "id":{"$le":"10"}
      • where object id property is less than equals to 10.
    • { "id": {"$in":["0", "100"]}}
      • where object id property is 0 or 100.
    • {"lineItems":{"lineAmount":"1"}}
      • where lineItems collection property of parameterized type has lineAmount equals to 1.
    • { "$and":[{"id": "0"}, {"billingAddress":{"city":"DEL"}}]}
      • where id property is 0 and billingAddress.city property is DEL.
    • {"lineItems":{"taxes":{ "key":{"code":"GST"}, "value":{"$gt": "1.01"}}}}
      • where lineItems collection property of parameterized type which has taxes map type property of parameteriszed type has code equals to GST value greater than 1.01.
    • {'$or':[{'code':'10'},{'skus': {'$and':[{'price':{'$in':['20', '40']}}, {'code':'RedApple'}]}}]}
      • Select all products where product code is 10 or sku price in 20 and 40 and sku code is "RedApple".
    0 讨论(0)
  • 2020-11-21 07:35

    How about some plain and straighforward Java

     List<Customer> list ...;
     List<Customer> newList = new ArrayList<>();
     for (Customer c : list){
        if (c.getName().equals("dd")) newList.add(c);
     }
    

    Simple, readable and easy (and works in Android!) But if you're using Java 8 you can do it in a sweet one line:

    List<Customer> newList = list.stream().filter(c -> c.getName().equals("dd")).collect(toList());
    

    Note that toList() is statically imported

    0 讨论(0)
提交回复
热议问题