QUESTION 4: METHODS AND CONTROL STRUCTURES

PART A: A number group represents a group of integers defined in some way. It could be empty, or it could contain one or more integers.

Write an interface named NumberGroup that represents a group of integers. The interface should have a single contains method that determines if a given integer is in the group. For example, if group1 is of type NumberGroup, and it contains only the two numbers -5 and 3, then group1.contains(-5) would return true, and group1.contains(2) would return false. Write the complete NumberGroup interface. It must have exactly one method.

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        NumberGroup rangeGroup = new RangeGroup(1, 10); // Represents numbers 1 through 10
        System.out.println(rangeGroup.contains(5));  // this is true
        System.out.println(rangeGroup.contains(11)); // this is false

        NumberGroup setGroup = new SetGroup(new HashSet<>(Arrays.asList(66, 63, 99)));
        System.out.println(setGroup.contains(66)); // this is true
        System.out.println(setGroup.contains(2));  // this is false
    }
//this checks if the number is there
    public interface NumberGroup {
        boolean contains(int num);
    }

    public static class RangeGroup implements NumberGroup {
        private int start, end;
//constructor
        public RangeGroup(int start, int end) {
            this.start = start;
            this.end = end;
        }
//to check if NumberGroup works with set of numbers
        @Override
        public boolean contains(int num) {
            return num >= start && num <= end;
        }
    }

    public static class SetGroup implements NumberGroup {
        private Set<Integer> numbers;
//constructor to start collection of numbers
        public SetGroup(Set<Integer> numbers) {
            this.numbers = numbers;
        }
//checks if number is in set
        @Override
        public boolean contains(int num) {
            return numbers.contains(num);
        }
    }
}

Main.main(null);

true
false
true
false

Part A Explanation

The NumberGroup interface defines a single method, contains(int num), which checks if a given integer is part of the group.

The RangeGroup class implements NumberGroup to represent a range of consecutive integers. It checks if a number is within this range in its contains method.

The SetGroup class implements NumberGroup using a Set to store its numbers, allowing for a collection of distinct integers without a specific order. Its contains method checks if the set contains the given number.

This example demonstrates how interfaces in Java can be used to define a common contract for different implementations, allowing for flexibility and reuse of code.

PART B: A range represents a number group that contains all (and only) the integers between a minimum value and a maximum value, inclusive. Write the Range class, which is a NumberGroup. The Range class represents the group of int values that range from a given minimum value up through a given maximum value, inclusive. For example, the declaration

NumberGroup range1 = new Range(-3, 2);

represents the group of integer values -3, -2, -1, 0, 1, 2.

Write the complete Range class. Include all necessary instance variables and methods as well as a constructor that takes two int parameters. The first parameter represents the minimum value, and the second parameter represents the maximum value of the range. You may assume that the minimum is less than or equal to the maximum.

public class Main {
    public static void main(String[] args) {
        NumberGroup range1 = new Range(-6, 5);
        System.out.println(range1.contains(-3)); // true
        System.out.println(range1.contains(0));  // true
        System.out.println(range1.contains(7));  // false
    }

    // Interface from Part A
    public interface NumberGroup {
        boolean contains(int num);
    }

    // Implementation of NumberGroup to represent a range of integers
    public static class Range implements NumberGroup {
        private int min;
        private int max;

        public Range(int min, int max) {
            this.min = min;
            this.max = max;
        }

        @Override
        public boolean contains(int num) {
            return num >= min && num <= max;
        }
    }
}

Main.main(null);
true
true
false

#### Part B Explanation

So basically, The NumberGroup interface with a single method contains(int num), which checks if a given integer is part of the group.

I also used Overrides to use it as a customization tag to make sure the right version of a method is used.

The Range class that implements the NumberGroup interface. It represents a range of integers from min to max (inclusive). The contains method for this class checks if a given integer falls within its range.

PART C: The MultipleGroups class (not shown) represents a collection of NumberGroup objects and isa NumberGroup. The MultipleGroups class stores the number groups in the instance variable groupList (shown below), which is initialized in the constructor.

private List groupList;

Write the MultipleGroups method contains. The method takes an integer and returns true if and only if the integer is contained in one or more of the number groups in groupList.

For example, suppose multiple1 has been declared as an instance of MultipleGroups and consists of the three ranges created by the calls new Range(5, 8), new Range(10, 12), and new Range(1, 6). The following table shows the results of several calls to contains.

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Create a list to hold NumberGroup objects, which are ranges in this context
        List<NumberGroup> groups = new ArrayList<>();
        // Add three Range objects to the list, each representing a different range of integers
        groups.add(new Range(5, 8));
        groups.add(new Range(10, 12));
        groups.add(new Range(1, 6));

        // Create a MultipleGroups object that contains all the ranges added above
        MultipleGroups multiple1 = new MultipleGroups(groups);
        
        // Test whether specific numbers are contained within any of the ranges in MultipleGroups
        System.out.println(multiple1.contains(2)); // true, because 2 is within the range 1-6
        System.out.println(multiple1.contains(9)); // false, 9 is not within any of the specified ranges
        System.out.println(multiple1.contains(6)); // true, because 6 is within the range 5-8 and 1-6
    }

    // Define the NumberGroup interface with a method to check if it contains a specific number
    public interface NumberGroup {
        boolean contains(int num);
    }

    // Implement the NumberGroup interface to represent a range of integers
    public static class Range implements NumberGroup {
        private int min; // The minimum value in the range
        private int max; // The maximum value in the range

        // Constructor to initialize a range with specified minimum and maximum values
        public Range(int min, int max) {
            this.min = min;
            this.max = max;
        }

        // Implement the contains method to check if a number is within the range
        @Override
        public boolean contains(int num) {
            return num >= min && num <= max;
        }
    }

    // Implement the NumberGroup interface to represent a collection of NumberGroup objects
    public static class MultipleGroups implements NumberGroup {
        private List<NumberGroup> groupList; // A list to hold the NumberGroup objects

        // Constructor to initialize MultipleGroups with a list of NumberGroup objects
        public MultipleGroups(List<NumberGroup> groupList) {
            this.groupList = groupList;
        }

        // Implement the contains method to check if any of the NumberGroup objects contain the number
        @Override
        public boolean contains(int num) {
            // Iterate through each NumberGroup in the list
            for (NumberGroup group : groupList) {
                // If any group contains the number, return true
                if (group.contains(num)) {
                    return true;
                }
            }
            // If no group contains the number, return false
            return false;
        }
    }
}
Main.main(null);
true
false
true

Part C Explanation

Here is how I would explain:

The NumberGroup interface is like the rule book that every club follows, saying, “Hey, to be part of us, you gotta pass this one test: are you in the right grade?”

The Range class is like a specific club that says, “We only take students from grade 5 to grade 8,” for example. When you check if you can join (contains method), they look at your grade and say yes or no based on their grade range.

Now, MultipleGroups is like a council of different clubs. When you ask if you can join any club in the council (contains method), they check with each club one by one. If any club says, “Yeah, this person can join,” then the council says you’re in. If none of the clubs accept you, the council says you’re not in.

In the main method, we’re setting up this scenario. We create a few clubs with their own grade ranges and then put them all in a council. Then we check a few grades to see if they’d be accepted by any club in the council.