I'm trying to make a method that returns an array of all found products. I'm a beginner in Java, so I've been thinking for hours and can't understand this.
Here is the code and the screenshot of what I've tried and the result:
public class ProductManager {
private ProductRepository repo;
public ProductManager(ProductRepository repo) {
this.repo = repo;
}
public void add(Product product) {
repo.save(product);
}
public Product[] searchBy(String text) {
Product[] result = new Product[0];
for (Product product : repo.findAll()) {
if (matches(product, text)) {
for (int i = 0; i < result.length ; i++)
result[result.length - 1] = product;
}
}
return result;
}
public boolean matches(Product product, String search) {
if (product.getName().contains(search)) {
return true;
} else {
return false;
}
}
}
In shouldFindProducts() method the test fails with:
org.opentest4j.AssertionFailedError: array lengths differ, expected: <1> but was: <0>
My TestClass:
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
public class ProductManagerTest {
ProductRepository repo = new ProductRepository();
ProductManager manager = new ProductManager(repo);
Product product1 = new Product(1, "футболка", 550);
Product product2 = new Product(2, "весна", 480);
Product product3 = new Product(45, "iphone 12", 34800);
#BeforeEach
public void setup() {
manager.add(product1);
manager.add(product2);
manager.add(product3);
}
#Test
public void shouldFindProducts() {
manager.matches(product2, "весна");
Product[] expected = {product2};
Product[] actual = manager.searchBy("весна");
Assertions.assertArrayEquals(expected, actual);
}
}
This is how the searchBy() method should be implemented with an ArrayList. Notice the method still returns an array by calling the toArray() method on the ArrayList object at the end. But the toArray() method returns an array of Object so you must cast it to Product, that is what the (Product[]) before the result.toArray() does.
Don't for get to import java.util.ArrayList;
public Product[] searchBy() {
ArrayList<Product> result = new ArrayList<Product>();
for (Product product : repo.findAll()) {
if (matches(product, text)) {
for (int i = 0; i < result.length ; i++)
result.add(product);
}
}
return (Product[])result.toArray();
}
Related
So I have 3 packages, Implementation, interfaces and test. I want to write the functionality into EmployeeImp so my unit test passes without error when I run it on TestEmployeeImp. However I'm not sure how getEmployeeCount is written as it fails in the unit test. I tried to solve it by creating the int count but it doesn't work. I know I need to use the array list to count the number of employees but I cannot come up with a solution and I can't find any samples of code that are like my unit test. If anyone can help it would be very appreciated.
//EmployeeImp
import java.util.ArrayList;
import java.util.List;
import interfaces.Employer;
import interfaces.Person;
public class EmployerImpl implements Employer {
private String name;
private List<Person> employees;
private int count;
public EmployerImpl(String n) {
//gets name
this.name = n;
//Array List
employees = new ArrayList<Person>();
// TODO Auto-generated constructor stub
}
#Override
public void hire(Person p, String title, double salary) {
p.setJob(null);
employees.add(p);
}
#Override
public List<Person> getEmployees() {
//Returns Employees in a List
return employees;
}
#Override
public int getEmployeeCount() {
return this.count;
//Returns employees size
}
#Override
public boolean fire(Person p) {
// TODO Auto-generated method stub
return false;
}
#Override
public String getName() {
//returns name
return name;
}
#Override
public boolean isEmployed(Person p) {
// TODO Auto-generated method stub
return false;
}
#Override
public Person getHighestPaid() {
// TODO Auto-generated method stub
return null;
}
#Override
public Person getLowestPaid() {
// TODO Auto-generated method stub
return null;
}
#Override
public double getStaffCost() {
// TODO Auto-generated method stub
return 0;
}
#Override
public int getCountOf(String title) {
// TODO Auto-generated method stub
return 0;
}
#Override
public List<Person> getAll(String title) {
// TODO Auto-generated method stub
return null;
}
}
//Employer.java
import java.util.List;
public interface Employer {
void hire(Person p, String title, double salary);
List<Person> getEmployees();
int getEmployeeCount();
boolean fire(Person p);
String getName();
boolean isEmployed(Person p);
Person getHighestPaid();
Person getLowestPaid();
double getStaffCost();
int getCountOf(String title);
List<Person> getAll(String title);
}
//TestEmployeeImp
import static org.junit.jupiter.api.Assertions.*;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import implementation.EmployerImpl;
import implementation.PersonImpl;
import interfaces.Employer;
import interfaces.Person;
class TestEmployerImpl {
private Employer e;
private Person highest;
private Person lowest;
#BeforeEach
void setUp() throws Exception {
e = new EmployerImpl("NCCO");
lowest = new PersonImpl("John", 18);
e.hire(lowest, "Lab Assistant", 20000);
highest = new PersonImpl("Anu", 50);
e.hire(highest, "Best Teacher", 80000);
e.hire(new PersonImpl("Damien", 18), "Teacher", 41000);
e.hire(new PersonImpl("Malachy", 45), "Teacher", 50000);
}
#Test
void testGetEmployees() {
List<Person> l = e.getEmployees();
assertNotNull(l);
assertEquals(4, l.size());
}
#Test
void testGetEmployeeCount() {
assertEquals(4, e.getEmployeeCount());
Person p = new PersonImpl("Paul H", 50);
e.hire(p, "teacher", 1000);
assertEquals(5, e.getEmployeeCount());
e.fire(p);
assertEquals(4, e.getEmployeeCount());
}
#Test
void testFire() {
Person p = new PersonImpl("Damien", 18);
boolean f= e.fire(p);
assertTrue(f);
assertEquals(3, e.getEmployeeCount());
p = new PersonImpl("Danika", 23);
f = e.fire(p);
assertFalse(f);
}
#Test
void testGetName() {
assertEquals("NCCO", e.getName());
}
#Test
void testIsEmployed() {
Person p = new PersonImpl("Damien", 18);
assertTrue(e.isEmployed(p));
p = new PersonImpl("Danika", 23);
assertFalse(e.isEmployed(p));
}
#Test
public void testGetHighestPaid() {
assertEquals(highest, e.getHighestPaid());
}
#Test
void getLowestPaid() {
assertEquals(lowest, e.getLowestPaid());
}
#Test
void getStaffCost() {
assertEquals(191000, e.getStaffCost());
}
#Test
void testGetCountOf() {
assertEquals(2, e.getCountOf("Teacher"));
assertEquals(0, e.getCountOf("Awesome Teacher"));
}
#Test
void testGetAll(){
assertEquals(2, e.getAll("Teacher").size());
assertNotNull(e.getAll("Dean"));
assertTrue(e.getAll("Dean").isEmpty());
}
}
I can't see any code which initialize or increment int count variable. But as you said, you don't need count variable and just use size() method in employees List
#Override
public int getEmployeeCount() {
return this.employees.size();
}
In #BeforeEach you're test by creating 4 employees.
Your hire method does 'employees.add(p);' , so it expands your list.
Your fire method does not do anything, just returning false.
Yet you expect in test testFire and testGetEmployeeCount that the number of employees has decreased. That does not happen and will fail.
You need the following fix:
IMPORTANT - Implement an equals and hash code on your PersonImpl class (so you can compare equal objects content instead of object-hash value). You can use guava or apache commmons or lombok or any other way to do that.
Then implement in 'fire' method:
#Override
public boolean fire(Person p) {
return employees.remove(p);
}
In this case I assume you will implement limitations in the 'hire' method on your class to have duplicate employees, so you need only to remove it once. If employees can be duplicate, then do to remove the employee including duplicates:
return employees.removeAll(Collections.singletonList(p));
An Aircraft is defined by the following Java class:
public class AirCraft
{
private String make;
private int numSeats;
public AirCraft(String make, int numSeats)
{
this.make = make;
this.numSeats = numSeats;
}
public String getMake()
{
return make;
}
public int getNumSeats()
{
return numSeats;
}
public String toString()
{
return make + " -> " + numSeats;
}
}
I have to write a method that takes a list of aircraft as a parameter that will find the names of aircrafts that have between 20 and 100 seats let's say and to return a new list that returns these aircraft and the number of seats they have. It has to be a static method of a Test class and must call medium(). This is what I have attempted thus far:
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class Test
{
// Add a static method called medium to this class.
public static void medium(AirCraft [] group)
{
List <String> aircrafts = new ArrayList<String>();
for(int i = 0; i < group.length; i++)
if(group[i].getNumSeats() >= 20 && group[i].getNumSeats() <= 100)
{
aircrafts.add(group[i]);
}
for(String str: aircrafts)
{
System.out.println(str.toString());
}
}
}
This is the test code:
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class AC
{
public static void main(String [] args)
{
AirCraft [] group = {
new AirCraft("Douglas", 110),
new AirCraft("Messerschmitt", 90),
new AirCraft("Boeing", 300),
new AirCraft("Lockheed", 90),
new AirCraft("Airbus", 70),
new AirCraft("Zeppelin", 1000),
new AirCraft("Victory", 55),
new AirCraft("McDonnellD", 63),
new AirCraft("Tupolev", 63),
};
// Convert array to a List
List<AirCraft> aircraft = Arrays.asList(group);
// Call the student's program
List<AirCraft> medium = Test.medium(aircraft);
for(AirCraft ac : medium)
System.out.println(ac);
}
}
Here are the problems.
public static void medium(AirCraft [] group)
change void to List<AirCraft>
List <String> aircrafts = new ArrayList<String>();
change to `List<AirCraft>`
and return your List<AirCraft> at the end of the method.
Change otherList<String> to List<AirCraft> where necessary
The following
for (String str : aircrafts) {
System.out.println(str.toString());
}
should be
for (AirCraft ac : aircrafts) {
System.out.println(ac);
}
And here
// Convert array to a List
List<AirCraft> aircraft = Arrays.asList(group);
// Call the student's program
List<AirCraft> medium = Test.medium(aircraft);
Why not just call medium with an array? Anyway, you are calling with a List but medium expects an array.
Here are the changes which seem to work.
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
public class AC {
public static void main(String[] args) {
AirCraft[] group = { new AirCraft("Douglas", 110),
new AirCraft("Messerschmitt", 90),
new AirCraft("Boeing", 300),
new AirCraft("Lockheed", 90),
new AirCraft("Airbus", 70),
new AirCraft("Zeppelin", 1000),
new AirCraft("Victory", 55),
new AirCraft("McDonnellD", 63),
new AirCraft("Tupolev", 63), };
// Convert array to a List
List<AirCraft> aircraft = Arrays.asList(group);
// Call the student's program
List<AirCraft> medium = Test.medium(aircraft);
for (AirCraft ac : medium)
System.out.println(ac);
}
}
class AirCraft {
private String make;
private int numSeats;
public AirCraft(String make, int numSeats) {
this.make = make;
this.numSeats = numSeats;
}
public String getMake() {
return make;
}
public int getNumSeats() {
return numSeats;
}
public String toString() {
return make + " -> " + numSeats;
}
}
class Test {
// Add a static method called medium to this class.
public static List<AirCraft> medium(List<AirCraft> planes) {
List<AirCraft> aircrafts = new ArrayList<>();
for (AirCraft ac : planes) {
if (ac.getNumSeats() >= 20
&& ac.getNumSeats() <= 100) {
aircrafts.add(ac);
}
}
for (AirCraft ac : aircrafts) {
System.out.println(ac);
}
return aircrafts;
}
}
i thing u should remove void and put List and add return aircrafts in the medium method
here is the code of C# which i am trying to convert
ArrayList.BinarySearch(Object, IComparer)
what it does is to comparer a node class object with a compare class object and returns -1, 0 or positive integer.
i have searched a lot and tried to convert it in java but could not do so. i'll need a method, instructions, library or anything that could help me achieve it.
class Class1
{
[STAThread]
static void Main(string[] args)
{
ArrayList SolutionPathList = new ArrayList();
//Create a node containing the goal state node_goal
Node node_goal = new Node(null,null,1,15,15);
//Create a node containing the start state node_start
Node node_start = new Node(null,node_goal,1,0,0);
//Create OPEN and CLOSED list
SortedCostNodeList OPEN = new SortedCostNodeList ();
SortedCostNodeList CLOSED = new SortedCostNodeList ();
//Put node_start on the OPEN list
OPEN.push (node_start);
}
SortedNode class is:
public class SortedCostNodeList
{
ArrayList _list;
NodeComparer _nodeComparer;
public SortedCostNodeList()
{
_list = new ArrayList ();
_nodeComparer = new NodeComparer ();
}
public int push (Node n)
{
int k = _list.BinarySearch (n,_nodeComparer);
if (k==-1) // no element
_list.Insert (0,n);
else if (k<0) // find location by complement
{
k=~k;
_list.Insert (k,n);
}
else if (k>=0)
_list.Insert (k,n);
return k;
}
and nodecomparer class is:
public class NodeComparer:IComparer
{
public NodeComparer()
{
}
public int Compare(object x, object y)
{
return ((Node)x).totalCost - ((Node) y).totalCost ;
}
}
i am unable to implement this piece of code
//int k = _list.BinarySearch (n,_nodeComparer);
any help?
You can use Arrays.binarySearch() to perform binary search on an array of Object.
I have created a sample program. Hope it helps.
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
#Getter #Setter
#AllArgsConstructor
class Node {
private long totalCost;
}
public class StackOverFlow {
public static void main(String... args) {
final List<Node> list = new ArrayList<>();
list.add(new Node(10));
list.add(new Node(20));
list.add(new Node(30));
list.add(new Node(40));
list.add(new Node(50));
list.add(new Node(60));
list.add(new Node(70));
final Node searchKey = new Node(60);
int index = Arrays.binarySearch(list.toArray(new Node[list.size()]), searchKey, new Comparator<Node>() {
#Override
public int compare(Node o1, Node o2) {
return (int) (o1.getTotalCost() - o2.getTotalCost());
}
});
System.out.print("Found at " + index);
}
}
Update:
Try this
class NodeComparator implements Comparator<Node> {
#Override
public int compare(Node o1, Node o2) {
return (int) (o1.getTotalCost() - o2.getTotalCost());
}
}
class SortedCostNodeList {
ArrayList<Node> list;
NodeComparator nodeCompartor;
public SortedCostNodeList() {
this.list = new ArrayList<>();
this.nodeCompartor = new NodeComparator();
}
public int push(Node n) {
int k = Arrays.binarySearch(this.list.toArray(new Node[list.size()]), n, this.nodeCompartor);
if (k == -1) // no element
this.list.add(0, n);
else if (k < 0) // find location by complement
{
k = ~k;
this.list.add(k, n);
} else if (k >= 0)
this.list.add(k, n);
return k;
}
// ...
}
I need a function to create instances of a dynamically given class in java.
I had found many samples but in all of them, the class to be instantiated was known before runtime.
There are user defined classes:
class Student { //some code }
class Teacher { //some code }
class Course { //some code }
What I need is
List<class> MyFunction(<class>) {
List<class> items = new ArrayList<class>();
for(int i = 0; i < 5; i++) {
create_a_new_class_instance;
items.add(new_created_instance);
}
return items;
}
How will I use
List<Student> students = MyFunction(Student);
List<Teacher> teachers = MyFunction(Teacher);
List<Course> courses = MyFunction(Course);
Hope someone helps.
This is my first question in Stackoverflow, sorry for any inconvenience.
Utku
In Java 8, you can use a method reference or lambda expression in order to create instances of classes dynamically without using reflection.
public static <T> List<T> myFunction(Supplier<T> supplier) {
return Stream.generate(supplier)
.limit(5)
.collect(Collectors.toList());
}
You would call it like:
List<Student> students = myFunction(Student::new);
If you're not familiar with streams, the imperative equivalent is:
public static <T> List<T> myFunction(Supplier<T> supplier) {
int size = 5;
List<T> list = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
list.add(supplier.get());
}
return list;
}
This should work.
import java.util.ArrayList;
import java.util.List;
public class DynamicClassList {
public <T> List<T> myFunction(Class<T> inputClass) {
List<T> items = new ArrayList<T>();
for(int i = 0; i < 5; i++) {
try {
T myT = inputClass.getConstructor().newInstance();
items.add(myT);
} catch (Exception e) {
e.printStackTrace();
}
}
return items;
}
public static void main(String[] args) {
DynamicClassList dynamicClassList = new DynamicClassList();
List<Student> s = dynamicClassList.myFunction(Student.class);
List<Teacher> t = dynamicClassList.myFunction(Teacher.class);
List<Course> c = dynamicClassList.myFunction(Course.class);
}
}
Assuming that the classes supplied to MyFunction have a default constructor, a simple implementation would be
public static <T> List<T> MyFunction(Class<T> clazz) {
if (clazz == null) {
return null;
}
T item;
List<T> items = new ArrayList<T>();
for (int i = 0; i < 5; i++) {
try {
item = clazz.newInstance();
} catch (Exception e) {
item = null;
}
if (item != null) {
items.add(item);
}
}
return items;
}
and the above method could be called like
List<Student> student = MyFunction(Student.class);
For increased transparency, the exception thrown inside the method could be handled in another way (e.g., added to the method signature).
You could use reflection to do this
each class you pass must have a default no-argument constructor.
for this specific application you will likely need all 3 classes to share an interface so that you can properly send a list back
public interface Unit {
//Put any common functionality method stubs here
}
public class Teacher implements Unit {
}
//....etc for the other classes
List<Unit> MyFunction(Class<Unit> clazz) {
List<Unit> items = new ArrayList<Unit>();
for(int i = 0; i < 5; i++) {
items.add(clazz.newInstance());
}
return items;
}
when you assign your list to a list variable you will have to cast it.
such as:
List<Student> students = (List<Student>) MyFunction(Student.class);
you can use a pattern stategy like this :
///interface
package strategy;
public interface IStrategy {
public void appliquerStrategy();
}
package tpdesignpattern2.strategy;
public class StrategyImpl1 implements IStrategy{
#Override
public void appliquerStrategy() {
System.out.println("Appliquer la strategy 1");
}
}
package tpdesignpattern2.strategy;
public class StrategyImpl2 implements IStrategy{
#Override
public void appliquerStrategy() {
System.out.println("Appliquer la strategy 2");
}
}
/////// Context class
package tpdesignpattern2.strategy;
public class Context {
/***
* injection de l'interface
*/
private IStrategy iStrategy = new StrategyImpl1() ;
/**
* #param iStrategy
*/
public void setiStrategy(IStrategy iStrategy) {
this.iStrategy = iStrategy;
}
public void appliquerStrategy() {
iStrategy.appliquerStrategy();
}
}
///Application
package tpdesignpattern2.strategy;
import java.util.Scanner;
import strategy.IStrategy;
public class App {
public static void main(String[] args) {
Context context = new Context();
Scanner scanner = new Scanner(System.in);
while(true) {
System.out.print("Entrer le nom de la calss : ");
String nom = "tpdesignpattern2.strategy."+scanner.nextLine();
tpdesignpattern2.strategy.IStrategy strategy;
try {
strategy = (tpdesignpattern2.strategy.IStrategy) Class.forName(nom).newInstance();
context.setiStrategy(strategy);
context.appliquerStrategy();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
};
}
}
}
I need to iterate through and ArrayList of objects and look for a variable that has the same value for multiple objects. As the example below, I am looking through an ArrayList, that has a sub-class . All I want to do is find out if a house or condo share the same listing number for this example code. I tried using a double loop, and an enhanced loop with a method (sameListingNum) and am having trouble working it out.
Thank you
// main client class
public static void main(String[] args)
{
ArrayList<House> listings = new ArrayList();
listings.add(new House(0001, 200000.00));
listings.add(new House(0201, 200000.00));
listings.add(new House(0001, 200000.00));
listings.add(new House(0401, 200000.00));
listings.add(new House(0031, 200000.00));
listings.add(new Condo(0401, 200000.00, 4));
listings.add(new Condo(0001, 120000.00, 3));
listings.add(new Condo(0301, 220000.00, 2));
listings.add(new Condo(0001, 130000.00, 3));
listings.add(new Condo(0201, 130000.00, 3));
for(House currentHouse: listings)
System.out.println(currentHouse);
for(int i=0; i<listings.size()-1; i++)
{
for(int j=i+1; j<listings.size(); j++)
{
}
}
// House Class
public class House
{
public int listingNum;
public double price;
public House()
{
listingNum = 0;
price = 0.00;
}
public House(int newListingNum, double newPrice)
{
listingNum = newListingNum;
price = newPrice;
}
public int getListingNum()
{
return listingNum;
}
public double getPrice()
{
return listingNum;
}
public String toString()
{
return ("Listing number: "+listingNum+", Price: "+price);
}
public boolean sameListingNum(Object other)
{
if(!(other instanceof House))
return false;
else {
House objHouse = (House)other;
if(listingNum - objHouse.getListingNum() == 0)
{
System.out.println("Same listing numbers: "
+listingNum+", "+objHouse.getListingNum());
return true;
}
else
return false;
}
}
}
// Condo Class
public class Condo extends House
{
public int connectedUnits;
public Condo()
{
super();
connectedUnits = 0;
}
public Condo(int newListingNum, double newPrice, int newConUnits)
{
super(newListingNum, newPrice);
connectedUnits = newConUnits;
}
public double getPrice()
{
return price;
}
public int getListingNum()
{
return listingNum;
}
public int getConnectedUnits()
{
return connectedUnits;
}
public String toString()
{
return super.toString()+", Number of connected unints: "+connectedUnits;
}
public boolean sameListingNum(Object other)
{
if(!(other instanceof House))
return false;
else {
House objHouse = (House)other;
if(listingNum - objHouse.getListingNum() == 0)
{
System.out.println("Same listing numbers: "
+listingNum+", "+objHouse.getListingNum());
return true;
}
else
return false;
}
}
You can group it using a Map of List, like Map> groups.
Then you loop over you list and for each house/condo you put it in the group of the same listing number. At the end you will have a map where for each entry there are all houses/condos with same listing number.
Here a sample:
Map<Integer, List<House>> groups = new HashMap<Integer, List<House>>();
for (House house:listings) {
List<House> group = groups.get(house.getListingNum());
if (group == null) {
group = new ArrayList<House>();
groups.put(house.getListingNum(), group);
}
group.add(house);
}
for (Entry<Integer, List<House>> entry:groups.entrySet()) System.out.println("Listing Number "+entry.getKey()+" Houses/condos: "+entry.getValue());
Both of the other 2 answers will work alternativly you can implement comparable on the House... eg.
public class House implements Comparable<House>
#Override
public int compareTo(final House o) {
return listingNum - o.listingNum;
}
then inside your main method. Sort the Collection and check to see if the previous row has the same Id all the time.
Collections.sort(listings);
int previousListing = Integer.MIN_VALUE;
for (House currentHouse : listings) {
if (currentHouse.getListingNum() == previousListing){
System.out.println("Duplicate for " + currentHouse.getListingNum());
}
previousListing = currentHouse.getListingNum();
}
take your pick.
Try this:
foreach(House h in listings)
{
if(listings.Exists(p => p.sameListingNum(h)))
{
//do something
}
}