Сложность фильтрации списка объектов с использованием потоков - PullRequest
0 голосов
/ 20 июня 2019

У меня есть один список List, необходимо написать общий код на основе потока, чтобы отфильтровать объекты в двух нижеприведенных сценариях.

  1. Входным параметром является dp со значением «MAR 2019». Если найдена какая-либо подходящая строка и дата окончания не равна нулю, верните строку.

    Введите:

    [PT(pn=1, endDate=2019-01-11, dp=MAR 2019),           
    PT(pn=4, endDate=null, dp=APR 2019),        
    PT(pn=6, endDate=2019-05-11, dp=MAY 2019)]       
    

    Выход:

    PT(pn=1, endDate=2019-01-11, dp=MAR 2019)}     
    
  2. Параметром для функции является «МАР 2019». Если найдена какая-либо подходящая строка и конечная дата равна нулю, необходимо возвращать все записи, пока мы не получим ненулевую конечную дату

    Введите:

    [PT(pn=1, endDate=null, dp=MAR 2019),      
    PT(pn=4, endDate=2019-04-11, dp=APR 2019),       
    PT(pn=6, endDate=2019-05-11, dp=MAY 2019)]      
    

    Выход:

    [PT(pn=1, endDate=null, dp=MAR 2019),      
    PT(pn=4, endDate=2019-04-11, dp=APR 2019)]  
    
class PT{       
   Integer pn;      
   Date endDate;      
   String dp;       
} 
List<PT> filteredList11 = availablePT.get()
    .stream()
    .sorted(Comparator.comparing(PT::getPn))
    .filter(e->)
    .collect(Collectors.toList());

Я немного запутался, как написать одну функцию фильтра для вышеупомянутых сценариев, так как мы никогда не фиксируем никаких предыдущих значений состояния при использовании потоков, добрый совет.

Ответы [ 2 ]

0 голосов
/ 20 июня 2019

Часть 1:

public static List<PT> filterOne(List<PT> input, String dp) 
{
    return input.stream()
             .filter(pt -> pt.endDate != null && pt.dp.equals(dp))
             .collect(Collectors.toList());
}

Часть 2:

public static List<PT> filterTwo(List<PT> input, String dp) 
{
    AtomicBoolean dpFilter = new AtomicBoolean(false);

    return input.stream()
            .filter(obj -> {
                if (dpFilter.get()){
                    if (obj.endDate == null || obj.dp.equals(dp)) {
                        dpFilter.set(false);
                        return false;
                    }
                    return true;
                }
                if (obj.endDate == null && obj.dp.equals(dp)){
                    dpFilter.set(true);
                    return true;
                }
                return false;
            })
            .collect(Collectors.toList());
}
0 голосов
/ 20 июня 2019

Вот пример метода, который делает то, что вы хотите сделать в первой части вашего вопроса . В основном это потоковое и фильтрует данный List<PT>, используя только один оператор .filter:

public class StackoverflowMain {

    static class PT {
        Integer pn;
        // Here, I changed your code. You should really use the up-to-date time API
        LocalDate endDate;
        String dp;

        public PT(int pn, LocalDate endDate, String dp) {
            this.pn = pn;
            this.endDate = endDate;
            this.dp = dp;
        }
    }

    /**
     * <p>
     * Gets a list of all PTs that match the given criterium for the dp class
     * attribute of class PT.
     * </p>
     *
     * @param source the original list that needs to be filtered
     * @param dp     the dp value to be matched
     * @return a list of all PTs that passed the filter criterium
     */
    public static List<PT> getPTWithValidEndDateAndDp(List<PT> source, String dp) {
        return source.stream()
                    .filter(pt -> pt.endDate != null && pt.dp.equals(dp))
                    .collect(Collectors.toList());
    }

    public static void main(String args[]) {
        // mock the list of PTs that you receive from somewhere
        List<PT> receivedPTs = new ArrayList<PT>();
        // one PT with endDate == null but matching dp
        receivedPTs.add(new PT(1, null, "MAR 2019"));
        // one PT with valid endDate and valid dp, but no matching dp
        receivedPTs.add(
            new PT(4, LocalDate.parse("2019-04-11", DateTimeFormatter.ISO_DATE), "APR 2019")
        );
        // another totally valid PT whose dp does not match
        receivedPTs.add(
            new PT(6, LocalDate.parse("2019-05-11", DateTimeFormatter.ISO_DATE), "MAY 2019")
        );
        // a totally valid PT with the matching dp ---> should be contained in the output
        receivedPTs.add(
            new PT(1, LocalDate.parse("2019-03-11", DateTimeFormatter.ISO_DATE), "MAR 2019")
        );

        // create a list from the valid and matching PTs passing the source list and the
        // dp to be matched
        List<PT> marchPTs = getPTWithValidEndDateAndDp(receivedPTs, "MAR 2019");

        // output the result
        marchPTs.forEach(mpt -> System.out.println("[pn: " + mpt.pn + ", endDate: "
                + mpt.endDate.format(DateTimeFormatter.ISO_DATE) + ", dp: " + mpt.dp + "]"));
    }
}

Обратите внимание, что я изменил часть вашего кода, я заменил старомодное и подверженное ошибкам использование java.util.Date на использование java.time.LocalDate, которое должно быть предпочтительным в настоящее время.

Не знаю, хватит ли у меня времени, чтобы привести пример для вашего второго требования, но я попробую ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...