Implement a method
public void search (String searchString) { }
to iterate through the notes ArrayList until it
finds a note that contains the searchString.
It should then print either the item found or
the message "String not found".
So far, I have:
import java.util.ArrayList;
import java.util.Iterator;
/**
* A class to maintain an arbitrarily long list of notes.
* Notes are numbered for external reference by a human user.
* In this version, note numbers start at 0.
*
* #author David J. Barnes and Michael Kolling.
* #version 2008.03.30
*/
public class Notebook
{
// Storage for an arbitrary number of notes.
private ArrayList<String> notes;
/**
* Perform any initialization that is required for the
* notebook.
*/
public Notebook()
{
notes = new ArrayList<String>();
}
/**
* Store a new note into the notebook.
* #param note The note to be stored.
*/
public void storeNote(String note)
{
notes.add(note);
}
/**
* #return The number of notes currently in the notebook.
*/
public int numberOfNotes()
{
return notes.size();
}
/**
* Show a note.
* #param noteNumber The number of the note to be shown.
*/
public void showNote(int noteNumber)
{
if(noteNumber < 0) {
// This is not a valid note number, so do nothing.
System.out.println("invalid index given");
}
else if(noteNumber < numberOfNotes()) {
// This is a valid note number, so we can print it.
System.out.println(notes.get(noteNumber));
}
else {
System.out.println("there are fewer items in the notebook");
// This is not a valid note number, so do nothing.
}
}
public void removeNote(int noteNumber)
{
if(noteNumber < 0) {
// This is not a valid note number, so do nothing.
System.out.println("invalid index given");
}
else if(noteNumber < numberOfNotes()) {
// This is a valid note number.
notes.remove(noteNumber);
}
else {
System.out.println("there are fewer items in the notebook");
// This is not a valid note number, so do nothing.
}
}
/* Edit note.
* I tried to improve the formatting of the code below, but I'm completely
* unable to figure out how on earth anything of that should make sense
* and therefore the indentation is completely without any meaning.
*/
public void search (String searchString)
{
for each notes in ArrayList {
if notes = searchString;
System.out.println("String found"); + searchString
return end
}
if}
System.out.println("String not found");
}
}
But it is not working, and I am not able to work it out.
Several problems:
Your search method is actually outside the class.
The body of your search method makes no sense at all.
If you're counting on the monkeys writing Shakespeare, you'll be waiting a while.
To iterate over the array list, you can use a 'for-each' loop:
for (String note: notes) {
// Do something with note
}
This is very basic syntax. Have you seen it before? If not, you should start by reading a very basic tutorial to Java before attempting this homework.
Fundamentally you need to look at each item in your ArrayList and test to see if it matches the search condition. In Pseudocode
for each note in notes
{
if note equals searchString then
print "Found " + searchString
return
end if
}
print "not found"
Given that basic outline, want to take a second stab at coding it in Java?
Basically you want to loop over the elements, and for each one check whether it equals the element you are searching for. You can use a for loop or a foreach loop to do the actual iteration.
should you be checking if the whole note matches your searchstring, or if the note contains your searchstring?
i.e. given notes "foobar","baz","spam", should a search on "foo" return "foobar" or not match on anything?
so in pseudocode:
for each note in notes
{
if searchstring in note
{
print "Found :"+note
}
}
check this website http://pleac.sourceforge.net/pleac_java/arrays.html it may be useful
Related
I am starting to learn Java and the content in which we learn from I just CANNOT get on with, it doesn't explain much but just gives you a mild example and tells you to do it yourself with something completely different. as above I need to take the 'longNumber' string and take the last character off it.
* Write a description of class CreditCardChecker here.
*
* #author Craig Beverley
* #version 03/12/2020
*/
public class CreditCardChecker
{
// Variable for long numbers to be checked
public String longNumber;
public StringBuilder firstFifteen;
/**
* Constructor for objects of class CreditCardChecker
* including long number and first fifteen
*/
public CreditCardChecker(String longNumber)
{
// initialise long number variable
this.longNumber=longNumber;
}
/**
* Sets the value of long number
*/
public void setLongNumber(String aLongNumber)
{
this.longNumber=aLongNumber;
}
/**
* method to get the long number
*/
public String getLongNumber()
{
return this.longNumber;
}
/**
* method to check that long number has exactly 16 digits
*/
public boolean isCorrectLength()
{
if (longNumber.length() == 16)
{
return (true);
}
else
{
return (false);
}
}
/**
* Method to get the first 15 characters of long number
*/
public String firstFifteen(String longNumber)
{
firstFifteen=longNumber.deleteCharAt(16);
}
}```
I'm not entirely sure you need firstFifteen as a field. You can simply grab the first 15 characters
return longNumber.substring(0, 15);
You also don't need a parameter for that method, since longNumber is a field
I need to add an Object to an ordered ArrayList depending on an attribute inside of the Object. I know how to use the .add method to add the object but I don't know how to search for the right place for it using the compareTo() method. And also I need to remove an Object from the ArrayList if the Object contains a certain String but I cant figure out how to access the Object attributes from the ArrayList.
Realtor Object
/**
* Constructor for Realtor object using parameter
* #param readData - array of data from line
*/
public Realtor(String[]readData){
licenseNumber = readData[2];
firstName = readData[3];
lastName = readData[4];
phoneNumber = readData[5];
commission = Double.parseDouble(readData[6]);
}
RealtorLogImpl
public class RealtorLogImpl {
private ArrayList<Realtor> realtorList;
/**
* Add Realtor object to ordered list
* #param obj - Realtor object
*/
public void add(Realtor obj){
//needs to be added into correct place depending on Realtor licenseNumber
realtorList.add(obj);
}
/**
* Delete Realtor object from list if license matches
* and return true if successful
* #param license
* #return
*/
public boolean remove (String license){
//need to remove Realtor with specific licenseNumber and return true if successful
}
I'm assuming you are using java 8. Some of these things have not been implemented in java 7 so keep that in mind.
First, to remove the items I would recommend using the removeif() method on the arraylist. This takes a lambda expression which could be something like x -> x.getString().equals("someString").
Second, You could add the object to the array then simply sort the array afterwards. You would just have to write a comparator to sort it by.
Here is some basic code; I have no compiler here, so you might find small errors/typos.
I'm sure there are better classes you can use instead of managing your own ordered list.
To insert:
public bool add(Realtor obj) {
int idx = 0;
for (Realtor s : realtorList) {
if (s.licenseNumber.equals(item.licenseNumber)) {
return false; // Already there
}
if (s.licenseNumber.compareTo(item.licenseNumber) > 0) {
orderedList.add(idx, item);
return true; // Inserted
}
idx++;
}
orderedList.add(item);
return true; // Appended
}
To delete:
public bool deleteItem(String license) {
int idx = 0;
for (Realtor s : realtorList) {
if (s.licenseNumber.equals(license)) {
realtorList.remove(idx);
return true; // Removed
}
}
return false; // Not found
}
To answer your question check the following snippet (requires Java 8) and adapt on your demand:
public static void main(String[] args) {
final List<String> list = new ArrayList<>();
list.add("Element 1");
list.add("Element 2");
list.add("Element 3");
/*
* Insert at a specific position (add "Element 2.5" between "Element 2" and "Element 3")
*/
Optional<String> elementToInsertAfter = list.stream().filter(element -> element.equals("Element 2")).findFirst();
if(elementToInsertAfter.isPresent()) {
list.set(list.indexOf(elementToInsertAfter.get()) + 1, "Element 2.5");
}
/*
* Remove a particular element (in this case where name equals "Element 2")
*/
list.removeIf(element -> element.equals("Element 2"));
}
#add(element) just adds an element to the list. In case of an ArrayList it's added at the end. If you want to insert an element at a particular position you need to use #set(index,element)
But instead of inserting your element at a particular position manually you should maybe use a comparator instead. See java.util.List.sort(Comparator<? super E> e)
Here are the errors I receive when running the tester class. I keep looking at where the code is pointing but I don't see where the issue is. It keeps saying I am also out of Java heap space, not sure what that is. I also am not sure if my recursive getsubset() method is even working correctly, as I can't even compile my tester class. If there are any other mistakes in my code be free to point them out. Thank you!
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:3209)
at java.lang.String.<init>(String.java:215)
at java.lang.StringBuilder.toString(StringBuilder.java:430)
at SubsetGenerator.getSubsets(SubsetGenerator.java:68)
at SubsetGenerator.getSubsets(SubsetGenerator.java:64)
at SubsetGeneratorTester2.main(SubsetGeneratorTester2.java:23)
Press any key to continue...
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/**
Prints subsets of String
*/
public class SubsetGenerator
{
private String word="";
private ArrayList<String> subsets;
/**
Constructs a word to generate subsets from
#param text input by user
*/
public SubsetGenerator(String textinput)
{
word=textinput;
subsets = new ArrayList<String>();
}
/**
retrieves word
#return the word
*/
public String getWord()
{
return word;
}
/**
get subsets
#return subset arraylist
*/
public ArrayList<String> getSubsets()
{
if(word.length() == 1)
{
subsets.add(word);
return subsets;
}
else
{
String removed = word.substring(0,1);
word = word.substring(1);
getSubsets();
for (int i = 0; i < subsets.size(); i++)
{
String temp = removed + subsets.get(i);
subsets.add(temp);
}
subsets.add(removed);
return subsets;
}
}
//sort subsets
public void sortSubsets()
{
Collections.sort(subsets);
}
}
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
/**
This program tests the subset generator.
*/
public class SubsetGeneratorTester2
{
public static void main(String[] args)
{
SubsetGenerator generator = new SubsetGenerator("rum");
List<String> subsets = generator.getSubsets();
// Sort the result for checking
Collections.sort(subsets);
System.out.println(subsets);
System.out.println("Expected: [, m, r, rm, ru, rum, u, um]");
}
}
The problem appears to be with the loop. If its not empty, an element is added so the size increases. Then since an element was empty, i+1 cannot ever be greater than or equal to the new size. This will very easily exhaust the heap. This fails however on the empty string with a runtime error immediately.
I can confirm that the loop is the culprit. Fixed this by simply moving the index out of the loop. That way it won't update as elements are added.
int size = subsets.size();
for (int i = 0; i < size; i++)
{
String temp = removed + subsets.get(i);
subsets.add(temp);
}
However, there was another issue.
Your method resulted in the set:
[m, r, rm, ru, rum, u, um]
This was easily changeable, since your base case was wrong. I also didn't want to modify too much of the code (but there is a better way to do this!)
In your example, the empty string would never work, however logically it should. The way I would handle this, is as follows (in pseudo code):
List subset(String str):
if(length == 0):
return [""];
x = subset(str.substring(1));
result = [];
for s in x:
result += [s, str.charAt(0) + s];
return result;
This of course is pseudo code (and close to python actually). I didn't want to give it all away, but the basic merit is to understand how these can be accomplished.
The important thing to note is that for each element, we add 2 strings to the list. One with the first character of the current string and one without the first character of the current string.
Consider some basic cases:
subset("") -> [""]
subset("a") -> ["", "a"]
subset("ab") -> ["", "a", "b", "ab"]
Hopefully you can see the pattern. For each string we add one with the character and one without.
I will give you another solution which is more clear than yours. First cut off a character from word. Then use that character to connect the remainder. Finally call getSubsets() recursively. If the word.length is zero, it reached the bottom and it will return.
public ArrayList<String> getSubsets(){
if(word.length()==0){
subsets.add("");
return subsets;
}
else{
String removed=word.substring(0,1);
word=word.substring(1);
subsets.add(removed);
for(int i=0;i<word.length();i++){
String temp=removed+word.substring(0,i+1);
subsets.add(temp);
}
}
getSubsets();
return subsets;
}
It's my anwser:
root#MQ-PC:/home/java/algorithm# java SubsetGenerator
[r, ru, rum, u, um, m, ]
I cannot see why this code is giving me the error cannot find method print everything looks okay to me, and I've been over the code checking for spelling errors and tried a different version of it that basically did the same thing but instead of things being called account they were called student. Ignore the comments as I have not changed them
import java.util.*;
public class AccountList
{
private ArrayList < Account > accounts;
/**
* Create a LabClass with no limit on number of enrolments.
* All other details are set to default values.
*/
public AccountList()
{
accounts = new ArrayList < Account >();
}
/**
* Add a account to this LabClass.
*/
public void addAccount(Account newAccount)
{
accounts.add(newAccount);
}
/**
* Return the number of accounts currently enrolled in this LabClass.
*/
public int getNumberOfAccounts()
{
return accounts.size();
}
/**
* Print out a class list with other LabClass
* details to the standard terminal.
*
* Method uses a for .. each loop
*/
public void getAllAccounts()
{
for(Account account : accounts)
{
**account.print();**
}
System.out.println("Number of accounts: " + getNumberOfAccounts());
}
/**
* Print out details of a account
* #param accountEntry The entry in the list
*/
public void getAccount(int accountEntry)
{
if(accountEntry < 0)
{
System.out.println("Negative entry :" + accountEntry);
}
else if(accountEntry < getNumberOfAccounts())
{
Account account = accounts.get(accountEntry);
System.out.print(account);
}
else
{
System.out.println("No such entry :" + accountEntry);
}
}
/**
* removes a account from the list
* #param accountEntry The entry in the list
*/
public void removeAccount(int accountEntry)
{
if(accountEntry < 0)
{
System.out.println("Negative entry :" + accountEntry);
}
else if(accountEntry < getNumberOfAccounts())
{
accounts.remove(accountEntry);
}
else
{
System.out.println("No such entry :" + accountEntry);
}
}
/**
* removes a account from the list
*
* #param aAccount the account to remove
*/
public void removeAccount(Account aAccount)
{
accounts.remove(aAccount);
}
}
You seem to be missing some fundamental concepts here.
First: you have no "default" .print() method; that is, the base, bare-bones Java class Object has no .print() method.
Second: even if it had, what do you expect it to do anyway? Where do you want it to print, what do you want it to print? The first question (where) is answered by classes dedicated to performing output duties (a PrintStream for instance), the second question (what) is answered by implementing your class' .toString().
Since you Account class is obviously not a class dedicated to output duties, you need to do two things:
make your Account class override .toString();
use a dedicated output class to print it; the fastest way to do this is to use System.out, which happens to be a PrintStream, which implements a .print() method.
Seeing your code it appears that you have a .printAccountDetails() method; this contradicts the Law of Demeter for starters; and note how it uses System.out.
Also, the difference between .print() and .println() in a PrintStream (which System.out is) is that a newline will be appended to the output if you use the "ln version"; custom has it that for most text based output channels, this also triggers an output flush from the underlying OS libraries.
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