I have included a block of code below that I just cannot seem to figure out what I am doing wrong. The code is part of a program that I am writing that populates an array list with virtual gas station objects containing several explicit parameters; one of which is a "description" that is a String parameter being the name of the gas station. The method in question, findStation(), takes an explicit parameter that is set to the name of a gas station. Then, using this I search through my array list looking for a gas station description(using a previously declared getDescription() method that I know functions correctly) that matches my toMatch explicit parameter. If a match is found, the integer position in which it is found is returned.
Well, I feel as if I have properly written the code, but when I attempt to do a Junit test on it, I get the error "Expected <6>, but returned <-1>". Does anyone see anything immediately wrong with either my method syntax or the way I am testing the method? Thanks in advance for all the help from you wonderful people!
By the way, I have tried to include everything that pertains to figuring out the specific method in question. Let me know if something else is needed!
Method in question: I create a temporary Station object to hold the information found at the "i" position in the list. Then, I create a temporary String to hold my description from the object I just retrieved. If the description matches the explicit parameter that is input, then I want it to return the index number at which it is found. My constant variable NO_MATCH is set equal to "-1", so my test is telling me that the gas station description does not exist when it clearly does.
public int findStation(String toMatch)
{
//returns the index where a match is found
for (int i = 0; i < stations.size(); i++)
{
Station tmpStation = stations.get(i);
String tmpDescription = tmpStation.getDescription();
if (tmpDescription.equals(toMatch))
{
return i;
}
}
return NO_MATCH;
}
Also, the addStation() method used to add stations.
public boolean addStation(double inLatitude, double inLongitude,
String inDescription, double inPrice, String inFuelType)
{
// Be sure inDescription is not a description in the collection
if (this.findStation(inDescription) == NO_MATCH)
{
Station tmpStation = new Station();
stations.add(tmpStation);
return true;
}
else return false;
}
Junit test including the setup() to give you an idea of what I'm working with.
protected void setUp()
{
// collection for testing
collection2 = new StationCollection();
// add stations to the collection
this.collection2.addStation(39.933611, -82.4725,
"Snake on the Lake", 2.99, "B80");
this.collection2.addStation(39.9621, -83.0005,
"Snake Central", 2.25, "E45");
this.collection2.addStation(39.94, -82.48,
"Snake Brothers", 2.27, "E45");
this.collection2.addStation(39.8614, -82.8916,
"Anna Conda Oil", 2.71, "PROPANE");
this.collection2.addStation(39.8614, -82.8916,
"Anna Conda Oil - II", 2.27, "E45");
this.collection2.addStation(39.9060, -82.7562,
"Tiger Snake", 2.31, "E40");
this.collection2.addStation(39.9611, -82.9988,
"Rattler Ray's", 2.15, "E84");
this.collection2.addStation(40.011792, -82.973196,
"Water Adder Oil", 3.20, "B80");
this.collection2.addStation(40.011792, -82.974,
"Water Adder Oil - II", 2.31, "E40");
}
public void testFindStation()
{
// Create an empty collection
StationCollection collection1 = new StationCollection();
// Attempt to find a station in the empty collection
assertEquals(StationCollection.NO_MATCH, collection1.findStation("Rattler Ray's"));
// Use non-empty collection2
// Look for position of matching station
assertEquals(6, collection2.findStation("Rattler Ray's"));
// Check that it detects a non-matching station
assertEquals(StationCollection.NO_MATCH, collection2.findStation("Sam Snake's"));
}
Related
While I know that this code should work to return the index, for some reason it's skipping the if statement and going straight to the else, when I know that the name is within the array, with the array that I'm using for testing. Won't even print the "if - reading" line.
public int find(String name)
{
int index = 0;
for(int i = 0; i < this.shoppingItems.length;i++)
{
if(this.shoppingItems[i].equals(name))
{
System.out.println("If - Reading");
index = i;
}
else
{
index = -1;
}
}
System.out.println(index);
return index;
}
//Main
ShoppingItem[] items = new ShoppingItem[]{new ShoppingItem("Eggs",3.2),new ShoppingItem("Bread",2.8),new ShoppingItem("Bacon",9),new ShoppingItem("Peas",2),new ShoppingItem("Spinach",4),new ShoppingItem("Chocolate",8)};
ShoppingList itemList = new ShoppingList(items);
itemList.find("Bread");
"While I know that this code should work to return the index, for some reason it's skipping the if statement and going straight to the else"
Stop! Java is not wrong; your code is, and it shouldn't work. Your if statement is not being skipped; it's just that the condition is always false, because this.shoppingItems[i] is a ShoppingItem object, and you are comparing it with name, which is a string. A ShoppingItem object is never equal to a string.
Presumably, what you want to test is whether the ShoppingItem object's name is equal to that string. Presumably, your class has a getName method, so you should test:
if(this.shoppingItems[i].getName().equals(name)) {
// ...
}
This is a common kind of programming error, perhaps because it's often acceptable in natural language to say one thing when you mean something closely related; e.g. you might say "I asked the help desk" when really you asked a person at the help desk, you did not ask the desk itself. This is a bit like that; you want the item's name to equal name, not the item itself.
Unless you are compelled to use arrays, you can make things much easier by using lists. They have quite a few useful features.
List<String> items = List.of("bread", "juice", "eggs", "milk");
System.out.println(find("eggs"));
System.out.println(find("butter"));
public int find(String name) {
return items.indexOf(name);
}
Prints
2
-1
That method of the List interface pretty much negates the need to write you own method. I just did it for demonstration purposes.
This example was using a List of Strings and not ShoppingItem class. You could get a List<ShoppingItem> to work by overriding the equals method in your class (something you should get in the habit of anyway).
And here is a taste of how would do it with Stream (java 8+). It presumes list is a simple array of ShoppingItem.
public int find(String name) {
return IntStream.range(0, list.length).filter(
i -> list[i].item.equalsIgnoreCase(name)).findFirst().orElse(-1);
}
I've been working on a problem:
"Design a program that asks the user for a series of names (in no particular order). After the final person’s name has been entered, the program should display the name that is first alphabetically and the name that is last alphabetically.
For example, if the user enters the names Kristin, Joel, Adam, Beth, Zeb, and Chris, the program would display Adam and Zeb."
I have a function called getString, which returns a valid string input; and a module called displayResults, which displays the first name alphabetically, and last name alphabetically. I also use "q" as a sentinel value to exit the while loop.
However, I am running into a problem where if I enter in names such as: "bob", "david", "alex", and "charlie", it will display the first name correctly as "alex", but will display the last name incorrectly as "charlie" instead of "david". I've tried looking through my code for an error, but wasn't able to locate where it's messing up. Any help is appreciated.
name = getString("Please enter a name, or input q to exit.");
if(!name.equals("q")) {
low = name;
high = name;
}
while(!name.equals("q")) {
int x;
x = name.compareToIgnoreCase(low);
if(x == -1){
low = name;
}
x = name.compareToIgnoreCase(high);
if(x == 1) {
high = name;
}
name = getString("Please enter another name, or input q to exit.");
}
displayResults(low, high);
The Java API documentation only states that compareToIgnoreCase() "Returns:
a negative integer, zero, or a positive integer". Since you are comparing x to 1 and -1 respectively it is possible you are actually receiving another value back and therefore the true "high" is not being detected.
Another possibility is that there may be invisible characters (like space or return) in your input. When I ran " david".compareToIgnoreCase("charlie") on my machine here it returned -67.
You could use a List which you sort then.
import java.util.List;
import java.util.Collections;
public class Main {
public static void main (String[] args) {
boolean run = true;
List<String> names = new List<String>();
while (run) {
String name = getString ();
if (name == "q") run = false;
else
names.add (name);
}
Collections.sort (names);
// Results:
System.out.println (names.get (0)); // Print out first entry
System.out.println (names.get (names.size() - 1)); // ... and last one
}
public static String getString () {
// Your method
}
}
In order to sort names you should use a collection that sorts the elements as you put them in.
For this porpose you can use the TreeSet implementation which is a sorted Set. Set also makes sure that no repeating elements are stored (for this it uses the compareTo method of the elements).
Also you can create a Collator object (which implements the comparator interface), which can use a locale object to sort the elements. It's easy to do localization based sorting with this method.
Please see the example below:
public static void main(String[] args) {
// Create the locale object
// This will be used when sorting the elements
Locale myLocale = Locale.ENGLISH;
// Locale myLocale = new Locale("HU", "hu");
// Locale myLocale = Locale.getDefault();
// Create the collator which will be responsible for using the locale object in order to compare the elements in the TreeSet
Collator coll = Collator.getInstance(myLocale);
coll.setStrength(Collator.PRIMARY);
// TreeSet for storing the elements
// Note that the TreeSet is instantiated with the collator object
TreeSet<String> names = new TreeSet<>(coll);
names.add("bob");
names.add("david");
names.add("alex");
names.add("charlie");
// You can call first and last method to get the first and last element sorted
System.out.println(names.first());
System.out.println(names.last());
}
I think this is the easiest, fastest, and most professional way of sotring elements since in this case you let java do the sorting for you, you only need to configure the way it should do it.
I hope this will be useful.
I'm new to OO. I've just started programming in Java for my university course.
I have a problem:
I have a method within the Club class to search for a member's name (or part of a name, according to my worksheet.
I have a class that tests this without me having to manually create objects from the Club class (I'm using BlueJ).
Here's the search method:
public void searchMember(String name){
i=0;
found = false;
while( i < members.size() && !found ){
if(members.contains( name )){
found = true;
}else{
i++;
}
}
if(found == true){
System.out.println(members.get(i));
}else{
System.out.println("Och Naw ... Member not found.");
}
}
And here is the testing class code:
public void demo()
{
club = new Club();
club.join(new Membership("Gordy Broon", 1, 1972));
club.join(new Membership("Eck Salmon", 9, 1965));
club.join(new Membership("Davie Caramel", 5, 1960));
System.out.println("Now doing some searching: ");
club.searchMember( "mon" );
System.out.println(" ");
System.out.println("And some more searching: ");
club.searchMember("moon");
System.out.println(" ");
}
Can someone explain to me why when searching for "mon" the result is not found?
To my understanding this should work.
I am new so ANY help and explanation would be amazing ^_^
Thanks!
You are comparing a String with a Membership. The contains method of List will go through every item in the list and check whether "mon".equals(membership), but a Membership object will presumably never return true that it is equal to some String.
(I am making an assumption about your Membership class, that you have not overridden the equals method from java.lang.Object. It would be possible to override equals so that it does return true when compared with a String, but there are two problems. One, you are expecting not just a match when they are equal, but a substring match (where "mon" matches "Eck Salmon"), and two, implementing equals this way would be a violation of its contract. It is expected that if a.equals(b) then b.equals(a), but no java.lang.String object is ever going to return true that it is equal to one of your Membership objects, and you can't modify java.lang.String to make it do that.)
What you want to do is go through the list and check if any of the membership objects have a name that contains "mon". I assume your Membership object has a getName() method:
for (Membership membership : members) {
if (membership.getName().contains(name)) {
System.out.println(membership);
return;
}
}
System.out.println("Och Naw ... Member not found.");
It is possible to do this a little more tersely in Java 8:
Optional<Membership> maybeMember = membership.stream()
.filter(m -> m.getName().contains(name)).findFirst();
String result = maybeMember.map(m -> m.toString())
.orElse("Och Naw ... Member not found.");
System.out.println(result);
This finds the first item in the list that matches the condition that its name must contain the specified name, and then maps it to a string using its toString method, or else uses the default string if no matching item from the list was found.
It seems that members is a list. So when you do members.contains( name ) it wont work. You beed to do the following members.get(i).getName().contains( name ).
I've been working at this for a couple hours now and I feel (I hope) I'm right on the verge of figuring it out. This program reads in a bunch of values from an external file and places them in an array of objects which seems to be working just fine.
The Objects properties are:
Bank Account #
Customer Name
Bank Account Balance
1. I can output them in order of Account # (That's how their read in from the file, no sorting is necessary)
2. I've setup a method from implementing Comparable to sort by Bank Account Balance and it's working fine.
3. I need a second sort method, to sort by Customer Name.
- The problem I'm having with this is based on the research I've done and what I've tried I've come to the conclusion that the only way to make this work will be to build my own Comparable Objects (sorry if my terminology is skewed.) I've attempted this as well multiple times with both Java Doc and some similar questions on SE.
When all is said and done I'm going to throw some Listeners into my checkbox group to allow the user to toggle the different sort methods.
Here's the chunks i'm working on:
public class bankAccounts implements Comparable<bankAccounts> {
/* PRIVATE FIELDS HERE, FOLLOWED BY TYPICAL GET AND SET METHODS */
/*SORTS BY ACCOUNT BALANCE WORKING GREAT*/
public int compareTo(bankAccounts b) {
if (accountBalance < b.accountBalance)
{
return -1;
}
if (accountBalance > b.accountBalance) {
return 1;
}
return 0;
}
/* BEGIN SNIPPET OF MAIN CLASS */
/*METHOD I CALL FROM MAIN CLASS, SORTS BY BALANCE ^^ AS SEEN ABOVE */
Arrays.sort(retrievedAccounts);
for (int i=0; i<retrievedAccounts.length; i++) {
String resultFull = Integer.toString(retrievedAccounts[i].getAccountNumber()) + retrievedAccounts[i].getAccountLastName() + Double.toString(retrievedAccounts[i].getAccountBalance());
box.append(resultFull + "\n");
}
/* NORMAL METHOD WHICH OUTPUTS IN ORDER OF ACCOUNT NUMBER, NO SORTING HAPPENING HERE */
for(int x = 0; x < retrievedAccounts.length; ++x)
{
String resultFull=Integer.toString(retrievedAccounts[x].getAccountNumber()) + retrievedAccounts[x].getAccountLastName() + Double.toString(retrievedAccounts[x].getAccountBalance());
box.append("\n\n\n" + resultFull + "\n\n");
}
I'm hoping someone will have some insight towards a next step which might allow me to finish this up. If you have suggestions to take this a completely different direction I'm open to that as well.
This is an idea haven't tested.
Create a another private method to store compareType
public class bankAccounts implements Comparable<bankAccounts> {
private int compareType = 0; // 0 - compare by balance 1-compare by name
In your compare method
public int compareTo(bankAccounts b) {
if(this.compareType == 0){
if (accountBalance < b.accountBalance)
{
return -1;
}
if (accountBalance > b.accountBalance) {
return 1;
}
return 0;
}else{
return customerName.compareTo(b.customerName)
}
Use an implementation of Comparator<bankAccounts> that compares the names of your objects and pass that into the Arrays.sort() method.
Use an anonymous class like this:
Arrays.sort(retrievedAccounts, new Comparator<bankAccounts>() {
public int compare(bankAccounts a, bankAccounts b) {
return a.getName().compareTo(b.getName());
}
});
This code assumes you have a getter method on bankAccounts for customer name called getName()
You would do well to follow java naming conventions:
class names start with a capital letter
class names are singular, not plurals
I've hit a roadblock with this program.
I have a program that involves creating a program that involves the "inventory" of Cadillac, and among all else, I cannot find answers to my questions.
I just do not know what to do. I'll provide the directions and then post the syntax I have so far.
Here is what I have to do:
inventory for a fictional Cadillac Dealership and allows the inventory to be searched to display a list of cars that meet specific criteria.
create an ADT class called Cadillac which contains four fields of instance data: Strings for model name, stock number and color, and an integer for price. The class contains one Constructor, which receives values for all four instance fields, and assigns the parameter values to the instance variables. The class also contains a simple accessor method and mutator method for each field of instance data.
When the program is ran, it loads the inventory from a file, "inventory.dat".
Here is a sample of the contents of the file:
DTS 11210 Glacier White 42706
Escalade 66502 Crimson Pearl 65547
XLR 58362 Radiant Bronze 78840
SRX 16218 Radiant Bronze 44522
Each line (each record) contains 4 fields of data: strings for model name, a 5–digit stock number, and color, and an integer for price. The delimiter between the fields is a tab character (“\t”).
In main(), create an array of Cadillac objects, read in a record from the file, split it into its 4 fields, create a Cadillac object and add it to the array.
the inventory file changes and your program needs to work no matter how many records are in the file. You are guaranteed there will never be more than 100 records in the file (they only have room for 100 cars on the lot), and that each record will contain exactly 4 fields of valid data.
The user can search the inventory two ways: by model name and by price. After you load the inventory, ask the user which search they want to do. If they indicate “by model name”, have them enter the name to search for. The valid model names are: DTS, Escalade, ESV, EXT, SRX, STS, and XLR. Search the inventory for all cars with that name and display a table of results on the console screen.
-When the user indicates he/she wants to search by price, have them enter the price to search
for, then perform the search, displaying all cars that have a price within $3,000 of the search
price.
- The program should loop to do as many searches as the user wants. Let the user end the
program by clicking a “Cancel” button when asked for the type of search they want to perform.
A “Cancel” button on the second question (the model or price to search for) should not end the
program, but your code should recognize it as an invalid entry, and not throw an exception.
Besides the list output, all input and output in the program should be with JOptionPane dialogs.
Here is what I have so far:
import java.util.Scanner;
import java.io.*;
public class Inventory {
public static void main ( String[] args )
{
String line;
String[] fields;
String[] items;
int count = 0;
int recCount;
Cadillac[] list = new Cadillac[100];
try
{
BufferedReader br = new BufferedReader( new FileReader( "inventory.dat" ) );
line = br.readLine();
while( line != null )
{
fields = line.split( "\t" );
items[count++] = new Cadillac( fields[0], fields[1], fields[2],
fields[3] );
line = br.readLine();
}
br.close();
}
catch( IOException e )
{
System.out.println( "Can't open input file. Program terminating." );
System.exit( 1 );
}
}
public static int loadArray(Cadillac[] items)
{
}
}
class Cadillac {
//Instance data
private String model;
private String stockNum;
private String color;
private int price;
//Constructor
public Cadillac(String mdl, String stckNum, String clr, int prc)
{
model = mdl;
stockNum = stckNum;
color = clr;
price = prc;
}
//Set of Accessor and Mutator Methods
public String getModel(){
return model;
}
public void setModel(String newModel){
model = newModel;
}
public String getStockNum(){
return stockNum;
}
public void setStockNum(String newStockNum){
stockNum = newStockNum;
}
public String getColor(){
return color;
}
public void setColor(String newColor){
color = newColor;
}
public int getPrice(){
return price;
}
public void setPrice(int newPrice){
price = newPrice;
}
}
PLEASE HELP! I do not have any other idea of what to do.
In regards to your comment:
It is saying that it cannot find the symbol constructor Cadillac
Your only constructor defined for Cadillac has parameters (String, String, String, int) but when you try to instantiate the object in main, you pass it four Strings. Java is throwing an error because it can't find the correct constructor.
Either pass the last parameter as an int or create a new constructor for your arguments.
Your most immediate problem is that the signature of your data objects constructor is incompatible with the way you are calling it. You have declared your constructor as so:
public Cadillac(String mdl, String stckNum, String clr, int prc)
It takes three string arguments and an int, but you are calling it with four strings:
new Cadillac( fields[0], fields[1], fields[2], fields[3] );
Thats the source of the compile error you reported seeing. You should convert your last String to an int.
new Cadillac( fields[0], fields[1], fields[2], Integer.parseInt(fields[3]).intValue() );
Apart from that there is another glaring error in your code. You declare an array of strings, but are attempting to store instances of 'Cadillac' into it:
String[] items;
// ...
items[count++] = new Cadillac( ... );
I won't code your entire homework for you, but my advise would be to first right down in plain English sentences, each task that needs to be accomplished in order to complete the overall program. Then start translating each individual sentence into code, ideally in the form of methods on your classes that can be called. As you run into issues, come back and ask specific questions and I'm sure there will be someone here willing to help you more.
Good luck.