Question 4: Methods and Control Structures
4a
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.List;
public class Main {
public static void main(String[] args) {
NumberGroup group1 = new IntegerList(Arrays.asList(100, 200));
System.out.println(group1.contains(100)); // true
System.out.println(group1.contains(300)); // false
}
// specific interface it is asking for part a
public interface NumberGroup {
boolean contains(int num);
}
public static class IntegerList implements NumberGroup {
private List<Integer> numbers;
public IntegerList(List<Integer> numbers) {
this.numbers = numbers;
}
@Override
public boolean contains(int num) {
return numbers.contains(num);
}
}
}
Main.main(null);
Output:
true
false
4a Explanation
I started by defining an interface named NumberGroup as instructed, which represents a group of integers and contains a single method called contains. This method checks if a given integer is present within the group. Next, I implemented this interface in a class called IntegerList, which utilizes a List
4b
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(100, 200);
System.out.println(range1.contains(150)); // true
System.out.println(range1.contains(175)); // true
System.out.println(range1.contains(300)); // false
}
// from part A
public interface NumberGroup {
boolean contains(int num);
}
public 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 number) {
return number >= min && number <= max;
}
}
}
Main.main(null);
Output:
true
true
false
4b Explanation
I began by defining a class named Range
that implements the NumberGroup
interface, representing a number group consisting of integers within a specified range. The Range
class includes two private instance variables, min
and max
, which denote the minimum and maximum values of the range, respectively. The constructor of the Range
class takes two integer parameters, setting the values of min
and max
accordingly. Within the contains method of the Range
class, I implemented the logic to determine whether a given integer falls within the specified range, utilizing a boolean expression that evaluates to true if the number is greater than or equal to min
and less than or equal to max
. Finally, in the main method, I instantiated a Range
object named range1 with minimum and maximum values of 100 and 200, respectively. Testing the contains method with various integers, I verified its correctness, where range1.contains(150)
and range1.contains(175)
both correctly returned true, while range1.contains(300)
appropriately returned false, demonstrating the successful implementation of the Range
class as a NumberGroup
.
4c
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.
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<NumberGroup> groups = new ArrayList<>();
groups.add(new Range(100, 200));
groups.add(new Range(300, 400));
groups.add(new Range(500, 600));
MultipleGroups multiple1 = new MultipleGroups(groups);
System.out.println(multiple1.contains(150)); // true
System.out.println(multiple1.contains(250)); // false
System.out.println(multiple1.contains(550)); // true
}
// from part A
public interface NumberGroup {
boolean contains(int num);
}
// from part B
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;
}
}
public static class MultipleGroups implements NumberGroup {
private List<NumberGroup> groupList;
public MultipleGroups(List<NumberGroup> groupList) {
this.groupList = groupList;
}
public boolean contains(int num) {
for (NumberGroup group : groupList) {
if (group.contains(num)) {
return true;
}
}
return false;
}
}
}
Main.main(null);
Output:
true
false
true
4c Explanation
I focused on implementing the contains method within the MultipleGroups
class. This class represents a collection of NumberGroup
objects and implements the NumberGroup
interface itself. The instance variable groupList
holds the NumberGroup
objects, initialized within the constructor. Within the contains method, I iterated through each NumberGroup
object in the groupList
using a for-each loop. For each group, I called its contains method to check if the provided integer is present within that group. If the contains method of any group returns true, indicating that the integer is found within at least one group, the contains method of MultipleGroups
returns true immediately. Otherwise, if none of the groups contain the integer, the method returns false. To demonstrate the functionality of the implemented solution, I instantiated an instance of MultipleGroups
named multiple1
with a list of NumberGroup
objects, specifically Range
objects representing different numerical ranges. Testing the contains method with various integers, I verified its accuracy in determining whether the integer is contained in one or more of the number groups in groupList
. For example, calling multiple1.contains(150)
correctly returned true, multiple1.contains(250)
returned false as expected, and multiple1.contains(550)
returned true, validating the successful implementation of the contains method within MultipleGroups
.
PersonJpaRepository (this code is related to this frq)
package com.nighthawk.spring_portfolio.mvc.person;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;
/*
Extends the JpaRepository interface from Spring Data JPA.
-- Java Persistent API (JPA) - Hibernate: map, store, update and retrieve database
-- JpaRepository defines standard CRUD methods
-- Via JPA the developer can retrieve database from relational databases to Java objects and vice versa.
*/
public interface PersonJpaRepository extends JpaRepository<Person, Long> {
Person findByEmail(String email);
List<Person> findAllByOrderByNameAsc();
// JPA query, findBy does JPA magic with "Name", "Containing", "Or", "Email", "IgnoreCase"
List<Person> findByNameContainingIgnoreCaseOrEmailContainingIgnoreCase(String name, String email);
/* Custom JPA query articles, there are articles that show custom SQL as well
https://springframework.guru/spring-data-jpa-query/
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods
*/
Person findByEmailAndPassword(String email, String password);
// Custom JPA query
@Query(
value = "SELECT * FROM Person p WHERE p.name LIKE ?1 or p.email LIKE ?1",
nativeQuery = true)
List<Person> findByLikeTermNative(String term);
/*
https://www.baeldung.com/spring-data-jpa-query
*/
}
Relation to the FRQ
Through inheritance, the PersonJpaRepository extends JpaRepository, showcasing method sharing and coherence, reflecting concepts tested in FRQs. In my project, I’ve implemented a repository interface called PersonJpaRepository using Spring Data JPA to handle database operations for the Person entity. This interface extends JpaRepository and provides several methods for interacting with person data stored in a relational database. For instance, I’ve defined methods like findByEmail to retrieve a person by their email address and findAllByOrderByNameAsc to fetch all persons ordered by name in ascending order. Additionally, I’ve included custom query methods like findByLikeTermNative to execute native SQL queries for more complex operations. This is related to this FRQ because I created a Java interface named NumberGroup and a class Range that implements this interface. The Range class represents a range of numbers specified by a minimum and maximum value, and it includes a method contains to determine if a given number falls within that range. To fulfill the requirement of checking if a number is contained within any group in a list of NumberGroup objects, I implemented a standalone method contains that iterates through the list and returns true if the number is found within any NumberGroup, otherwise returning false. ```