জাভা স্ট্রিম: একাধিক ব্যাপ্তির ফিল্টার


9

আমি একটি উত্স ফিল্টার করার চেষ্টা করছি এবং একটি ক্ষেত্রের উপর ভিত্তি করে কিছু উপাদান বাদ দিতে চাই। বাদ দেওয়ার জন্য আমার একটি সেট রয়েছে (এতে একটি আইডি রয়েছে যা বাদ দিতে হবে) এবং একটি তালিকা রয়েছে (এটিতে একাধিক আইডির বাদ দেওয়া দরকার)। আমি নীচের যুক্তিটি লিখেছি এবং আমি ২ য় ফিল্টার যুক্তিতে সন্তুষ্ট নই। জাভা 8 দিয়ে এটি করার আরও ভাল কোনও উপায় আছে কি? রেঞ্জগুলি অন্তর্ভুক্ত করার জন্য আমারও এটি করা দরকার।

Set<String> extensionsToExclude = new HashSet<>(Arrays.asList("20","25","60","900"));
List<String> rangesToExclude = new ArrayList<>(Arrays.asList("1-10","20-25","50-70","1000-1000000"));
return directoryRecords.stream()
        .filter((directoryRecord) -> !extensionsToExclude.contains(directoryRecord.getExtensionNumber()))
        .filter((directoryRecord -> {
            Boolean include = true;
            for(String s : rangesToExclude) {
                String [] rangeArray = s.split("-");
                Integer extension = Integer.parseInt(directoryRecord.getExtensionNumber());
                if(extension <= Integer.parseInt(rangeArray[0]) && extension >= Integer.parseInt(rangeArray[1])) {
                    include = false;
                }
            }
            return include;
        }))
        .collect(Collectors.toList());

ধন্যবাদ :)


3
Booleanযখন আপনার কেবল একটি booleanমান প্রয়োজন তখন অবজেক্টগুলি ব্যবহার করবেন না । যদিও এখানে, ভেরিয়েবল includeসম্পূর্ণ অপ্রচলিত। যখন একমাত্র সম্ভাব্য পরিবর্তন থেকে trueথেকে false, আপনি প্রতিস্থাপন করতে পারেন include = false;সঙ্গে return false;শেষ ফলাফল হিসেবে ইতিমধ্যে নির্ধারিত হয়েছে। তারপরে, return include;শেষে এটিকে দ্বারা প্রতিস্থাপিত করা যায় return true;এবং ভেরিয়েবল ঘোষণা সরিয়ে ফেলা যায়। যেহেতু directoryRecordলুপ পরিবর্তন না, আপনি স্থানান্তর করতে পারেন Integer extension = Integer.parseInt(directoryRecord.getExtensionNumber());লুপ সামনে (এবং পরিবর্তন Integerকরার জন্য int)।
হোলার

উত্তর:


9

আমি এটি একটি কাস্টম Rangeক্লাস দিয়ে করব, এরকম কিছু:

class Range {
    private long start;
    private long end;

    Range(String start, String end) {
        this.start = Long.parseLong(start);
        this.end = Long.parseLong(end);
    }

    Range(String range) {
        this(range.split("-")[0], range.split("-")[1]);
    }

    boolean inRange(long n) {
        returns start <= n && n <= end;
    }
}

যা এ জাতীয় কিছু সম্ভব করে তুলবে:

List<Range> ranges = rangesToExclude.stream()
                     .map(Range::new).collect(Collectors.toList());
return directoryRecords.stream()
        .filter((directoryRecord) -> !extensionsToExclude
                                    .contains(directoryRecord.getExtensionNumber()))
        .filter(directoryRecord -> ranges.stream()
                                    .noneMatch(r -> r.isInRange(directoryRecord)))
        .collect(Collectors.toList());

আমি ব্যক্তিগতভাবে আপনার প্রথম ফিল্টারটি যথাযথভাবে সংরক্ষণ করার মতো দেখতে পাই।


2
noneMatchআমরা যখন কথা বলছি তখন কি এমন হওয়া উচিত নয় rangesToExclude? এবং আমি মনে করি, একটি এর সাথে আরও মার্জিত সমাধান হতে পারে TreeSet<Range>...
হোলার

আসলেই আমার ঘুম হওয়া উচিত ছিল।
আর্নেস্ট_ কে

@ernest_k সমাধানের জন্য আপনাকে ধন্যবাদ। আমি এটি সত্যিই মার্জিত মনে।
ইয়াদবেন্দ্র রাঠোর

4

আমি এর্নস্ট_ কে এর উত্তরটির সাথে অনুরূপ পরামর্শ দেব Range

তবে এই পদ্ধতির মধ্যে আপনি উভয় সংগ্রহ তৈরি করতে ব্যবহার করতে পারেন List<Range>(এটি "20"হিসাবে বিবেচনা করা যেতে পারে "20-20") এবং ফিল্টার শর্তটি অবহেলা করার জন্য পরিবর্তন করতে পারেন anyMatch

List<Range> ranges = Stream.concat(extensionsToExclude.stream(), rangesToExclude.stream())
        .map(Range::creatRange).collect(Collectors.toList());

return directoryRecords.stream()
        .filter(directoryRecord -> !ranges.stream()
                .anyMatch(r -> r.isInRange(
                        Integer.parseInt(directoryRecord.getExtensionNumber()))
                ))
        .collect(Collectors.toList());
class Range {
    private int start;
    private int end;

    Range(String start, String end) {
        this.start = Integer.parseInt(start);
        this.end = Integer.parseInt(end);
    }

    static Range creatRange(String range) {
        if (range.contains("-")) {
            return new Range(range.split("-")[0], range.split("-")[1]);
        }
        return new Range(range, range);
    }

    boolean isInRange(int n) {
        return start <= n && n <= end;
    }
}

হালনাগাদ

যে List<Range> rangesবিন্দু থেকে Set<String> extensionsToExcludeতৈরি রেঞ্জের মধ্যে রয়েছে সেগুলি থেকে পয়েন্টগুলি সরিয়ে ফেলতে সৃষ্টি পরিবর্তন হতে পারে List<String> rangesToExclud। তাহলে অপ্রয়োজনীয় রেঞ্জ তৈরি করা হবে না।

List<Range> ranges = rangesToExclude.stream().map(Range::creatRange)
        .collect(Collectors.toCollection(ArrayList::new));
extensionsToExclude.stream()
        .filter(v -> !ranges.stream()
                .anyMatch(r -> r.isInRange(Integer.parseInt(v))))
        .map(Range::creatRange)
        .forEach(ranges::add);

0

সমস্ত এন্ট্রি মূল্যায়নের অপেক্ষা না করে সীমা শর্তটি সত্য হলে আপনি একটি প্রাথমিক বিরতি করতে পারেন।

if(extension >= Integer.parseInt(rangeArray[0]) && extension <= Integer.parseInt(rangeArray[1])) {
                    return true;
                }

অন্যথায় কেবল লুপের পরে মিথ্যা ফিরিয়ে দিন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.