Instructions:

(a) NumberGroup Interface:

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.

(b) Range Class:

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.

(c) MultipleGroups Class:

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.

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:

Call Result
multiple1.contains(2) true
multiple1.contains(9) false
multiple1.contains(6) true

Reflection

  • For me this was the hardest FRQ, as it tested the advanced parts of java by testing the idea of polymorphism between the classses which truly made it hard for me having to make me spend time a lot and look at lessons and watch videos to completly understand.

Part A

import java.util.HashSet;
import java.util.Set;
// initial methods with a signle value. 
public class CustomNumberGroup implements NumberGroup {
    private Set<Integer> numbers;

   
    public CustomNumberGroup() {
        this.numbers = new HashSet<>();
    }

   
    public void addNumber(int number) {
        numbers.add(number);
    }

    @Override
    public boolean contains(int number) {
        return numbers.contains(number);
    }


    public void printNumbers() {
        System.out.println("Numbers in the group:");
        for (int num : numbers) {
            System.out.println(num);
        }
    }

    public static void main(String[] args) {
       
        CustomNumberGroup group1 = new CustomNumberGroup();

       
        group1.addNumber(-5);
        group1.addNumber(3);

        // Testing contains method
        System.out.println("group1.contains(-5): " + group1.contains(-5)); 
        System.out.println("group1.contains(2): " + group1.contains(2));   

   
        group1.printNumbers();
    }
}
CustomNumberGroup.main(null)
group1.contains(-5): true
group1.contains(2): false
Numbers in the group:
3
-5

Part B

public class Range implements NumberGroup {
    private int min;
    private int max;

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

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

    public static void main(String[] args) {

        // Creating a range from -3 to 2
        Range range1 = new Range(-3, 2);

        // Testing contains method
        System.out.println("range1.contains(-5): " + range1.contains(-5)); // Should return true
        System.out.println("range1.contains(3): " + range1.contains(3));   // Should return true
        System.out.println("range1.contains(5): " + range1.contains(5));   // Should return false
    }
}
Range.main(null)
range1.contains(-5): false
range1.contains(3): false
range1.contains(5): false

Part C

import java.util.List;

public class MultipleGroups implements NumberGroup {
    private List<NumberGroup> groupList;

    // Constructor
    public MultipleGroups(List<NumberGroup> groupList) {
        this.groupList = groupList;
    }

   
    @Override
    public boolean contains(int num) {
        for (NumberGroup group : groupList) {
            if (group.contains(num)) {
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
      
        List<NumberGroup> groups = List.of(new Range(5, 8), new Range(10, 12), new Range(1, 6));

        
        MultipleGroups multiple1 = new MultipleGroups(groups);

        
        System.out.println("multiple1.contains(2): " + multiple1.contains(2)); // Should return true
        System.out.println("multiple1.contains(9): " + multiple1.contains(9)); // Should return false
        System.out.println("multiple1.contains(6): " + multiple1.contains(6)); // Should return true
    }
}
MultipleGroups.main(null)
multiple1.contains(2): true
multiple1.contains(9): false
multiple1.contains(6): true

Interfaces

  • Interfaces in Java define a set of method signatures that classes must implement, serving as a contract for behavior.
  • They facilitate loose coupling by allowing classes to interact through common interfaces rather than specific implementations.
  • Java interfaces can include constants, which are implicitly public, static, and final.