I have used the comparable interface before but using it with generic objects and a second object has been causing me some difficulties
Here is my driver program
import java.io.*;
import java.util.*;
public class Prog2 {
public static void main (String[]args){
//Declare Variables
Scanner inFile = null;
ListArray<Part> partArray = new ListArray<Part>(13);
//Open the file
try {
inFile = new Scanner(new File("parts.txt"));
}
//If the file is not found, end the program
catch(FileNotFoundException e){
System.out.println("Error: File not found");
System.exit(0);
}
//While the file has new text, read it in
while(inFile.hasNext()){
//Read a line of code in
String temp = inFile.nextLine();
//split the line into an array
String[] tempA = temp.split(",[ ]*");
//place the specific info into variables
int pnum = Integer.parseInt(tempA[0]);
String name = tempA[1];
double price = Double.parseDouble(tempA[2]);
String warN = tempA[3];
int quant = Integer.parseInt(tempA[4]);
//add the info into an object
partArray.add(new Part(pnum, name,price,warN,quant));
}
}
}
The class meant to be written like an Array list
public class ListArray <E extends Comparable>{
//Declare Variables
private E[] list;
private int size;
//Construct Constructor
public ListArray(){
list = (E[]) new Comparable[10];
}
public ListArray(int capacity){
list = (E[]) new Comparable[capacity];
}
/*This method will allow users to get the variable stored
* at the index they specify
* #param: int index: the index of the wanted item
* #return: E: the item at the speicifed index */
public E get(int index){
return list[index];
}
/*This method will allow users to add an element to the
* end of the list array
* #param: E item: the item being added to the array */
public void add(E item){
list[size] = item;
size++;
}
/*This mehod will allow the user to find a specified item
* inside of the array
* #param: E target: the item the user wants to know the index of
* #return: int: the index of the item found */
public int find(E target){
for(int i = 0; i < size; i++){
if(target.compareTo(list[i]) == 0){
return i;
}
}
return -1;
}
/*This method will allow users to get the size of the array
* #return: int: the size of the array */
public int size(){
return size;
}
}
and the Part class that reads in from a csv file.
public class Part <E extends Comparable>{
//Declare Variables
private int pnum;
private String name;
private double price;
private String warh;
private int quant;
//Construct Constructor
public Part(){
pnum = 0;
name = "";
price = 0.0;
warh = "";
quant = 0;
}
public Part(int pnum, String name, double price, String warh, int quant){
this.pnum = pnum;
this.name = name;
this.price = price;
this.warh = warh;
this.quant = quant;
}
//Getters
public int getPnum(){
return pnum;
}
public String getName(){
return name;
}
public double getPrice(){
return price;
}
public String getWarh(){
return warh;
}
public int getQuant(){
return quant;
}
//Setters
public void setPnum(int pnum){
this.pnum = pnum;
}
public void setName(String name){
this.name = name;
}
public void setPrice(double price){
this.price = price;
}
public void setWarh(String warh){
this.warh = warh;
}
public void setQuant(int quant){
this.quant = quant;
}
When I run the program, I am given this error inside of the console
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
Bound mismatch: The type Part is not a valid substitute for the bounded parameter of the type ListArray
Bound mismatch: The type Part is not a valid substitute for the bounded parameter of the type ListArray
at Prog2.main(Prog2.java:8)
From the looks of it, this is a problem of how COmparable is implemented in one of my classes, and it not being correctly implemented in the other. I tried looking at other posts on the website and tried implementing them to no avail. Thank you so much!
You have specified your ListArray to only be paramtrizable with types that extend Comparable
ListArray <E extends Comparable>
But, you're trying to parametrize it with Part, which does not extend Comparable.
It looks like you've made some mistake in making Part generic. You should have Part implement Comparable i.e. :
public class Part implements Comparable<Part>
And then implement the compareTo method in Part
#Override
public int compareTo(Part other) {
// ... code here
}
Your problem here stems from the fact that you declared the Part class of using a generic E which extends the Comparable interface.
Same goes for your ListArray class, in which you define it again as accepting a E which extends the Comparable interface.
When you try to create a new ListArray by doing so:
ListArray<Part> partArray = new ListArray<Part>(13);
it'll effectively expect something that is within bounds, in this case this being something that implements the Comparable interface. Since your Part object does not do so, this is reason why you get this error (also the compiler message is quite informative about this).
I would generally suggest you have a good read on generics if you attempt to use them, as it seems that you're lacking in understanding them.
Related
I'm using Bluej to create a basic Java project which I'm not supposed to use Arrays or collections and I'm having difficulty to understand how I can display a specific existing object from another class.
Here's my Class Listing:
public class Listing
{
//name of the listing
private String listingName;
//number of the listing
private int listingNumb = 0;
//price of the listing
private double price;
//checks if the listing is for sale
private boolean isForSale;
//House data of the listing
private HouseData housedata;
private boolean isSold;
/**
* Constructor for objects of class Listing
*/
public Listing(String newListing, double newPrice, HouseData housedata)
{
listingName = newListing;
listingNumb++;
price = newPrice;
isForSale = false;
this.housedata = housedata;
isSold = false;
}
//Returns if the listing is sold or not
public boolean getIsSold(){
return isSold;
}
//Set the listing as sold or not
public boolean setIsSold(){
isSold = true;
return isSold;
}
//returns if the listing is for sale or not
public boolean getIsForSale(){
return isForSale;
}
//set the listing for sale or not
public boolean setIsForSale(boolean sale){
isForSale = sale;
return isForSale;
}
//Return the price of the listing
public double getPrice(){
return price;
}
//Return the listing name
public String getListingName(){
return listingName;
}
//Return the listing number
public int getListingNumb(){
return listingNumb;
}
//checks if the listing is located at a specific city
public boolean isLocatedAt(String city){
if(housedata.city() == city){
return true;
}else{
return false;}}
public double getSurface(){
return housedata.getSurface();
}
}
Here's my Class RealEstateAgency where I want to call the objects from class Listing:
public class RealEstateAgency
{
//the name of the agency
private String agency;
//the amount of profit from property sales
private double profit;
//identifies the seller of the property
private String agent;
private boolean isOnSale;
//the name of the property
private Listing listing;
private Listings lists;
/**
* Constructor for objects of class RealEstateAgency
*/
public RealEstateAgency()
{
profit = 0;
}
//Returns total profit from agency
public double getProfit(){
return profit;
}
//Display listing that is on sale with the name of one city
//This is the method where I want to retrieve all listing existing objects that have a specific city
public void displayListingsLocatedAt(String city){
System.out.println("The available listings for this city are: " + ;
}
}
And this is the main class where I initialize the objects:
public class AppStart
{
public static void main(String[] args)
{
Address address1 = new Address("street", "postalcode", "city");
HouseData house1 = new HouseData(2, true, address1);
Listing list1 = new Listing("Imóvel1", 9000, house1);
Listing list2 = new Listing("Imóvel2", 9000, house1);
Listing list3 = new Listing("Imóvel3", 8000, house1);
RealEstateAgency real1 = new RealEstateAgency();
}
}
Thing is, you are creating these Listing classes that are not part of any class. After your initialization of RealEstateAgency, there should be a call something like this:
real1.listing = list1;
(I think it will work, altough it's set to private...)
It will add your list1 into your real1 object, then able to call it's getters like
real1.listing.getPrice();
Or something like this.
Thing is, you can reach the class variables by the dot selector, even if that variable is an another class, in that case you can use your selectors as a chain.
However, with your current setup, you can hold only 1 Listing in each RealEstateAgency, plus I don't think "Listings lists" works. Either that's an errorenous code, or part of your code is missing that explains that line.
An another note, your listingNumb currently does nothing, since it's held by the Listing class, so after calling the constructor of a Listing, it will be just set to 1 all the time.
I want to get the model numbers from the list only
['brand: Samsung, model number: VA2210-MH, size: 21.5', 'brand: Philipe, model number: 244E1SB, size: 21.5']
And I set create attributes and getter and setter of all attributes(only model number will be shown) in Monitor
public class Monitor{
public String brand;
public String modelNumber;
public double size;
public Monitor(String brand, String modelNumber, double size){
this.brand = brand;
this.modelNumber = modelNumber;
this.size = size;
}
public void setModelNumber(String amodelNumber){
modelNumber = amodelNumber;
}
public String getModelNumber(){
return modelNumber;
}
}
so I create a list and add the information into the list
and a method to create a set with model number by the method modelNumberSet()
import java.util.*;
public class ComputerShop{
private List<Monitor> monitorList = new ArrayList<>();
public void addMonitor(String brand, String modelNumber, double size){
Monitor newMonitor = new Monitor(brand, modelNumber, size);
monitorList.add(newMonitor);
}
public Set<Monitor> modelNumberSet(){
Set<Monitor> NewSet = new HashSet<>();
for (Monitor m : monitorList) {
NewSet.add(m.getModelNumber());
}
return NewSet;
}
}
I hope the model number will be added into a new set, the output looks like
[VA2210-MH, 244E1SB]
So I use for loop to incase I will add more information in the future, but the error comes out when I use add(). Why the array cannot be added into the new set? Am I using the wrong function?
Is there a better solution I should use?
Change Set<Monitor> to Set<String>. You are adding model numbers to the set and their types are String. You are trying to put a String where a Monitor is expected. Square peg in a round hole.
Fix the modelNumberSet() method as follows:
public Set<String> modelNumberSet(){
Set<String> newSet = new HashSet<>();
for (Monitor m : monitorList) {
newSet.add(m.getModelNumber());
}
return newSet;
}
I have created a class like this, which contains a bunch of arraylist as you can see. I've been setting the array with the methods add.. and then retrieving it with get.., when i tried to System.out.println numberofcitizen for example it is returning 0. Note that i have instantiated the class in another class to set the values.
public int numberOfCitizen;
private final ArrayList<Integer> citizenid = new ArrayList<>();
private final ArrayList<String> citizenName = new ArrayList<>();
private final ArrayList<Integer> citizenWaste = new ArrayList<>();
private final ArrayList<Float> longitude = new ArrayList<>();
private final ArrayList<Float> latitude = new ArrayList<>();
private final ArrayList<String> address = new ArrayList<>();
public void working() {
System.out.println("executing fine");
}
public void setnoOfcit(int number) {
this.numberOfCitizen = number;
}
public int getnumber() {
return this.numberOfCitizen;
}
public void addCitizenId(int citizen) {
citizenid.add(citizen);
}
public int getCitizenid(int i) {
int citId = citizenid.get(i);
return citId;
}
public void addCitizenName(String citizenname) {
citizenName.add(citizenname);
}
public String getCitizenName(int i) {
return citizenName.get(i);
}
public void addCitizenWaste(int waste) {
citizenWaste.add(waste);
}
public int getCitizenWaste(int i) {
return citizenWaste.get(i);
}
public void addLatitude(float lat) {
latitude.add(lat);
}
public float getLat(int i) {
return latitude.get(i);
}
public void addlng(float lng) {
longitude.add(lng);
}
public float getlng(int i) {
return longitude.get(i);
}
com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder vrpBuilder = com.graphhopper.jsprit.core.problem.VehicleRoutingProblem.Builder.newInstance();
public void runVPRSolver() {
System.out.println(numberOfCitizen);
System.out.println(getCitizenName(0));
//create a loop to fill parameters
Probable source of problem :
numberOfCitizen is a member attribute that you seem to never change. If you want it to represent the number of elements in your lists, either use citizenName.size() or increment the value of numberOfCitizen in one of the add methods.
Design flaw :
Your design takes for granted that your other class always use that one properly. Anytime you or someone uses that class, he must make sure that he add every single element manually. This adds code that could be grouped inside your class, which would be cleaner and easier to maintain.
So instead of several add method like this :
addCitizenid();
addCitizenName();
addCitizenWaste();
addLongitude();
addLatitude();
addAddress();
Design an other Citizen class which will contain those elements, and use a single list of instances of that class. That way you can use only one method :
private List<Citizen> citizenList = new ArrayList<>();
public void addCitizen(Citizen c) {
/*Add element in your list*/
citizenList.add(c);
}
This programming methodology is called "Encapsulation" which you can read about here
You need to increment numberOfCitizen in your add methods. For example:
public void addCitizenId(int citizen){
citizenid.add(citizen);
numberOfCitizen++;
}
I would also suggest encapsulating your variables into Objects, so create a citizen class:
public class Citizen {
private Integer id;
private Integer name;
private Integer waste;
}
And change your variable to an ArrayList of objects:
ArrayList<Citizen> citizens;
OK so I have the following Object class:
public class IntoleranceFood implements Comparable<IntoleranceFood>{
private int scoreInt;
public String foodName;
public IntoleranceFood(String food, int score) {
super();
this.foodName = food;
this.scoreInt = score;
}
//getters and setters
public String getFood() {
return foodName;
}
public void setFood(String food) {
this.foodName = food;
}
public int getScore() {
return scoreInt;
}
public void setScore(int score) {
this.scoreInt = score;
}
#Override
public String toString() {
return "Intolerance Food [Name=" + foodName + ", Score=" + scoreInt + "]";
}
#Override
public int compareTo(IntoleranceFood arg0) {
return toString().compareTo(arg0.toString());
}
}
And then in my Activity I have created an array for these objects to go into, and filled up the array with "IntoleranceFood" Objects:
int numFoodItemTypes = db.intoleranceFoodItemTypesTotal();
IntoleranceFood[] foodArray = new IntoleranceFood[numFoodItemTypes];
Cursor cAllFoodTypes = db.intoleranceFoodTypesList();
int foodItem = 0;
do{
foodArray[foodItem] = new IntoleranceFood(cAllFoodTypes.getString(0), 0);
foodItem++;
}while(cAllFoodTypes.moveToNext());
I managed to sort the array by implementing Comparable and the compareTo method in my Object class:
Arrays.sort(foodArray);
But I want to then search the array using binary search, and look for the position in the array where a certain Object with a specific food name (String) resides. But I dont know how to get the following code working, and specifically in terms of:
-binarySearch(Object[] array, Object value)
I don't know what to put in "Object value" so this:
Arrays.binarySearch(foodArray, "Cereal");
Is clearly wrong! But I'm not sure how to search the Object array for an Object containing the String food name "Cereal".
Thanks.
Yes so after the very useful reply below, I realsied what I need to be doing is:
IntoleranceFood searchOb = new IntoleranceFood("Cereal",0);
int searchIndex = Arrays.binarySearch(foodArray, searchOb);
And that works!
In my opinion your mistake is
Arrays.binarySearch(foodArray, "Cereal");
because "Cereal" is not the Object you are looking for and your array doesnt contain this object. The second parameter should be an instance of the IntoleranceFood class and "Cereal" is just a property of that class.
For your problem i would use a HashMap or another Map who fits your problem best!
Maybe this article will help you : How to sort a HashMap in Java
I have following homework about computer store:
There are several class include: Monitor, Case, Mouse, Keyboard.
All the classes have common fields: id, name, price, quantity.
Each class has some unique fields.
All most features are: add, update, delete, find, show list, save, load file
-So, first I will create a class named Product have 4 common fields. Above classes will extends from Product.
-Then, I think I maybe create a ComputerStore class which have a field is items type ArrayList. items stores all objects which are instance of 4 above classes But I'm not sure.
Whether it is reasonable? I need some ideas
Before , I always use ArrayList store for only one class like
List <String> list = new ArrayList<String>();
Now they are multi type. I think it's generic in Java, right??
In case, I want to update for 1 items. I must think about how to change information for them. Ex: mouse for some code, keyboard for another code. Anyway, thank for everybody!
Your approach is 100% reasonable.
You are completely on the right track with "generics". First, check out the official enter link description here.
Next, just think about your data in real world terms, like you are already doing: Monitor, case, mouse, and keyboard are products. Your computer store's inventory is a list of products.
Hint: A list of products.
Put that together with what you learn about generics through that tutorial, and you'll be good to go.
You could use java generic.First create a java collection (ex: List) with supper class type, Product. Now you could add any sub classes (Monitor , Keyboard etc) in your collection (List) that extends of class Product.
public class Product{
}
public class Monitor extends Product{
}
public class Keyboard extends Product{
}
List<Product> products = new ArrayList<Product>();
products.add(new Monitor());
products.add(new Keyboard());
Since you have a superclass (Product), you can have the list's type as Product, i.e.
List<Product> list = new ArrayList<Product>();
list.add(new Mouse());
list.add(new Keyboard());
It will allow you to iterate them and list their name and price without caring for the class, but if you intend to take an item out of the list you'll need to check its actual type (depending on what you do with it).
You can do like below
import java.util.List;
import java.util.ArrayList;
class Test{
public static void main(String... args){
List<MultiObj> multiObjs = new ArrayList();
MultiObj ob = new MultiObj(); multiObjs.add(ob);
ResX xOb = new ResX(); multiObjs.add(xOb);
ResY yOb = new ResY(); multiObjs.add(yOb);
ResZ zOb = new ResZ(); multiObjs.add(zOb);
for (int i = 0; i < multiObjs.size(); i++ ) {
System.out.println(multiObjs.get(i).getV());
}
System.out.println("Waoo its working");
}
}
class MultiObj{
public String greet(){
return "Hello World";
}
public String getV(){
return "Hello World";
}
}
class ResX extends MultiObj{
String x = "ResX";
public String getX(){
return x;
}
public String getV(){
return x;
}
}
class ResY extends MultiObj{
String y = "ResY";
public String getY(){
return y;
}
public String getV(){
return y;
}
}
class ResZ extends MultiObj{
String z = "ResZ";
public String getZ(){
return z;
}
public String getV(){
return z;
}
}
You could do this:
public class Item {
public Item(int id, string name, float price, int amount, int ArrayID) {
if (ArrayID == 1) {
ID1 = id;
name1 = name;
price1 = price;
amount1 = amount;
}
if (ArrayID == 2) {
ID2 = id;
name2 = name;
price2 = price;
amount2 = amount;
}
if (ArrayID == 3) {
ID3 = id;
name3 = name;
price3 = price;
amount3 = amount;
}
if (ArrayID == 4) {
ID4 = id;
name4 = name;
price4 = price;
amount4 = amount;
}
}
//ArrayID #1
public static int ID1;
public static String name1;
public static float price1;
public static int amount1;
//ArrayID #2
public static int ID2;
public static String name2;
public static float price2;
public static int amount2;
//ArrayID #3
public static int ID3;
public static String name3;
public static float price3;
public static int amount3;
//ArrayID #4
public static int ID4;
public static String name4;
public static float price4;
public static int amount4;
public static int[] id = ID1, ID2 ID3, ID4;
//so forth...
}