简体   繁体   中英

Java: How to apply filters to set?

In my program I've different scenarios

In the beginning set will be empty like this:

[]

User can add values in the set dynamically let say user enter start and end integers as 2 and 6, set will be like this:

[2,3,4,5,6]

A) What user can do:

After user can do like this let say user enter 1 and 2, set will be like this:

[1,2,3,4,5,6]

User can also do like this let say user enter 6 and 8, set will be like this:

[1,2,3,4,5,6,7,8]

B) What user cannot do is this:

Let say user enter 2 and 6 as 2,3,4,5,6 is already present in the set, so program should output error message to the user.

User also cannot do, let say user enter 0 and 10 as 0, 1,2,3,4,5,6,7,8 ,9,10 bold integers are already present in set, so program should output error message to the user.

C) Final Result:

In the end set should be like this [1,2,3,4,5,6,7,8]

Update:

User can also do like this, say in the beginning set is empty like this:

[]

User enter 1 and 3, set will be like this:

[1,2,3]

Afterwords user enter 5 and 7, set will be like this:

[1,2,3,5,6,7]

After user enter 3 and 5, set will be like this

[1,2,3,4,5,6,7]

How can I achieve this, any help would be greatly appreciated.

What I've tried so far is not working:

Scanner reader = new Scanner(System.in);

System.out.println("Enter a start: ");
int s = reader.nextInt();

System.out.println("Enter a end: ");
int e = reader.nextInt();

Set<Double> filterSet = new TreeSet<>();


for (int i = s; i <= n; i++) {            
    if(filterSet.stream().allMatch(x -> x>=s && x<=e)){
        System.out.println("Error");
        }
        else{
            filterSet.add(i);
            }
}

The reason your stream expression is not working is because your definition of a range is not consistent. This inconsistency creates many edge-cases that you must test when deciding whether or not the result is valid. Some examples (from your update):

Starting with an empty set, Ø , union it with [1,3] ( note that this is a closed set from mathematics ) giving the result {1,2,3}

Union the previous result with [5,7] ( another closed set ) resulting in {1,2,3,5,6,7}

Union that result with (3,5) ( notice that this is an open set ) resulting in {1,2,3,4,5,6,7}

If we stopped here, you could create a coherent rule where the computation is considered successful if the cardinality of the result is greater than the cardinality of the original set, |currentValue| > |previousValue| |currentValue| > |previousValue| . However, you provided an example in your original post where you computed the union of [0,10] with [1,8] where this rule fails (ie, values {0,9,10} were added to the set). Even though the cardinality of the result, 11, is greater than the cardinality of the previous value, 8, the computation is considered a failure.

You could even be generous and consider all new inputs to be open sets, [1,8] ∪ (0,10) ⇔ [1,8] ∪ [1,9] ( notice the change from open to closed sets ), but this would still result in one change that you were not expecting ( 9 was added to the set), hence the need for testing edge cases.

A similar case exists where you start with the set [2,6] (ie, {2,3,4,5,6} ) and union it with [1,2) ( notice the partially open set ) that results in [1,6] (ie, {1,2,3,4,5,6} ), which is considered a success even though it results in a single change like the previous example. In this case, the element 1 is added to the set rather the element 9 .

In one case, I've added an element to the end of the sequence and in the other case, I've add the element at the beginning of the sequence. Why should these be treated differently?

You should not expect a quality answer to your question until you provide a consistent way to determine whether the result is valid.

See: notation

I achieved what I wanted by using Google Guava's RangeSet interface . Thanks to @shmosel who pointed this out to me.

Scanner reader = new Scanner(System.in);

System.out.println("Enter a start: ");
int s = reader.nextInt();

System.out.println("Enter a end: ");
int e = reader.nextInt();

RangeSet<Integer> rangeSet= TreeRangeSet.create();

            if(rangeSet.isEmpty()){
                System.out.println("1 Empty");
                rangeSet.add(Range.closed(s, e));
            }else {
                System.out.println("1 Not Empty");
                if(!rangeSet.encloses(Range.closed(s, e)) && !rangeSet.intersects(Range.open(s, e))){
                    System.out.println("2 Yes");
                    rangeSet.add(Range.closed(s, e));
                }else{
                    System.out.println("2 No");
                }
            }
            System.out.println("Range: " + rangeSet) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM