Java Impementing an interface. With additional functions - java

Hello ive added two new functions to the implementation of an interface.
this is the implementation file...
import au.edu.uow.Collection.Album;
import java.util.ArrayList;
public class CDAlbum implements Album {
private String Title;
private String Genre;
private String Artist;
private String MediaType;
private ArrayList<String> trackList;
public CDAlbum(String TempTitle, String TempGenre, String TempArtist, ArrayList<String> TempTracklist, String TempMediaType){
//Set initail variable values
Title = TempTitle;
Genre = TempGenre;
Artist = TempArtist;
trackList = TempTracklist;
MediaType = TempMediaType;
}
//Accessor Functions
public String getMediaType(){
//Return Media Type
return MediaType;
}
public String getTitle(){
//Return Title
return Title;
}
public String getGenre(){
//Return Genre
return Genre;
}
public String getArtist(){
//Return Artist
return Artist;
}
public ArrayList<String> getTrackList(){
//Return Tracklist
return trackList;
}
}
The bottom two functions are the added functions( getArtist(), getTrackList())
the problem im having is that when i try to call these functions from a class file it give me the following errors.
./au/edu/uow/UserInterface/UserInterface.java:95: cannot find symbol
symbol : method getArtist()
location: interface au.edu.uow.Collection.Album
System.out.println(albumCollection.get(number).getArtist());
^
./au/edu/uow/UserInterface/UserInterface.java:98: cannot find symbol
symbol : method getTrackList()
location: interface au.edu.uow.Collection.Album
ArrayList<String> trackList = albumCollection.get(number).getTrackList();
When i call the functions
import au.edu.uow.Collection.Album;
System.out.println(albumCollection.get(number).getArtist());
//Access the track titles
ArrayList<String> trackList = albumCollection.get(number).getTrackList();
//Output collection
int arrayListSize = trackList.size();
for(int i = 0; i < arrayListSize; i++)
{
System.out.println( i + ": " + trackList.get(i));
}

Album specifies neither getArtist nor getTrackList:
public interface Album {
/**
* This method returns the media type of the album.
* #return the media type of the album, either CD or DVD
* #see #getTitle()
* #see #getGenre()
*/
String getMediaType();
/**
* This method returns the title of the album.
* #return the title of the album
* #see #getMediaType()
* #see #getGenre()
*/
String getTitle();
/**
* This method returns the genre of the album.
* #return the genre of the album
* #see #getTitle()
* #see #getMediaType()
*/
String getGenre();
}
... only CDAlbum does.
You can determine whether the Album is a CDAlbum or DVDAlbum by checking Album.getMediaType; then, if it is a CD, you can cast to CDAlbum and invoke getArtist and getTrackList then.
for (final Album album : albumCollection) {
final String type = album.getMediaType();
System.out.print(type + " album: " + album.getTitle()
+ " (" + album.getGenre() + ") - ");
if (type.equals("CD")) {
final CDAlbum cd = (CDAlbum) album;
System.out.println(cd.getArtist());
int n = 0;
for (final String track : cd.getTrackList()) {
System.out.printf("#%2d - %s\n", ++n, track);
}
} else {
final DVDAlbum dvd = (DVDAlbum) album;
System.out.println(dvd.getDirector());
System.out.println(dvd.getPlotOutline());
}
}

Is Album the return type of albumCollection.get(number)? If so, then you need to add getArtist and getTrackList method into your interface as well.

When you add new method in your interface you must implement in your implementation class.
check the type of albumCollection.get(number)
if albumCollection.get(number) return Album then you can call getArtist()

Create a super class say for example MasterAlbums and extend your CDAlbum and DVDAlbum from it.Place the methods getArtist() & getTrackList() in the super class.Do not override it in the subclasses.Now when you call System.out.println(albumCollection.get(number).getArtist()); , It will refer to the superclass method and your artist & tracklist will be printed.

Related

A search method that finds a string value in an String Array

So I am trying to create a method that finds a title in a ArrayList of photos.
public class Album {
private String albumtitle;
private ArrayList<Photo> photos;
/**
* This constructor should initialize the
* instance variables of the class.
*/
public Album(String title) {
this.albumtitle = title;
photos = new ArrayList<>();
}
This is the code I have got to for trying to search for a specific title of the photo. I am not sure if i should put (int index) or (String title) in the methods parameters.
public Photo searchByTitle(int index) {
if (index >= 0 && index < photos.size()) {
String title = photos.get(index);
System.out.println(title);
}
return null;
}
I am beginner programmer, and I feel a little guidance will help a lot.
Edit: So lots of people are telling me to use for loops. My project requires me to not do for loops for methods, hence why I have displayed it in this way.
I'll give you an example the lecturer gave us:
https://lms.uwa.edu.au/bbcswebdav/pid-1134902-dt-content-rid-16529804_1/courses/CITS1001_SEM-2_2018/lectures/BooksReadJournal.java.pdf
She doesn't use for loops.
You could use the stream-API:
Arrays.stream(photos).filter(p -> p.getTitle().equalsIgnoreCase(searchTitle)).findFirst().orElseGet(...);
You iterate over each photo called p in this array and compare p's title with the one you search and return the first match.
Or simply use a normal for-loop:
for(int i = 0; i < photos.size(); i++) {
if(photos[i].getTitle().equalsIgnoreCase(searchTitle)){ return photos[i]; }
return new ErrorPhoto(); //or some error state
}
More enhanced for-each-loop:
for(Photo p: photos) {
if(p.getTitle().equalsIgnoreCase(searchTitle)) { return p; }
return new ErrorPhoto(); //or some error state
}
You iterate over each photo and compare its title with the one you search and return the first match:
for(int i = 0; i < photos.size, i++) {
if(photos.get(i).getTile().equals("title name"){
System.out.println("Found the title");
}
}
Your current code will always return null. If this is a search method to return the found object, you return the object if it is found. If not found, then return null:
public Photo searchByTitle(String title) {
for(Photo p : photos)
if(p.getTitle().equals(title))
return p;
return null;
}
This is the code I have got to for trying to search for a specific title of the photo. I am not sure if i should put (int index) or (String title) in the methods parameters
Since the method name itself suggested searchByTitle, whoever is using this method would expect it to receive String title.
If it is to be searched by index, then there can be another method as such:
public Photo searchByIndex(int index){
}
You have two options for a search, either you look a Photo up by its title or by its index. If your class had both methods, it would look like this:
public class Album {
private String albumtitle;
private ArrayList<Photo> photos;
/**
* This constructor should initialize the instance variables of the class.
*/
public Album(String title) {
this.albumtitle = title;
photos = new ArrayList<>();
}
/**
* Searches the {#link Photo} with the given title.
* #param title the title of the desired {#link Photo}
* #return the {#link Photo} with the given title or
* <code>null</code> if it is not in the list
*/
public Photo searchByTitle(String title) {
// initialize with null to return that if the photo was not found
Photo photo = null;
// iterate all photos and check if one of them has the title
for (int i = 0; i < photos.size(); i++) {
if (title.equals(photos.get(i).getTitle())) {
photo = photos.get(i);
// exit the loop when the photo was found
break;
}
}
return photo;
}
/**
* Searches the {#link Photo} with the given index.<br>
* Checks if the index is valid in the list of {#link Photo}s
* #param index the index of the {#link Photo}
* #return the {#link Photo} with the given index or <code>null</code>
* if it is not in the list or the index is invalid.
*/
public Photo searchByIndex(int index) {
try {
// use the method of the list to get the photo
return photos.get(index);
} catch (IndexOutOfBoundsException ioe) {
// print some error message for the case of an invalid index
System.err.println("The given index is not available!");
return null;
}
}
}
package simple;
import java.util.ArrayList;
public class Album {
private static String albumtitle;
public Album(String title) {
Album.albumtitle = title;
}
public Photo searchByTitle(ArrayList<Photo> photos) {
if (index >= 0 && index < photos.size()) {
Photo title = photos.get(index);
if (title.getTitle().equals(albumtitle))
System.out.println("tile Found" + title);
}
return null;
}
public static void main(String[] args) {
ArrayList<Photo> photos = new ArrayList<>();
//Searching title2 or u can pass as parameter
Album album = new Album("title2");
for (int i = 0; i < 5; i++) {
Photo photo = new Photo();
photo.setTitle("Title" + i);
photos.add(photo);
}
album.searchByTitle(photos);
}
}
package simple;
public class Photo {
String title;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
Are looking for this..?

get several method's return values from a class in one statement

Item searchByPattern(String pat)
{
for(Iterator iter = items.iterator(); iter.hasNext(); )
{
Item item = (Item)iter.next();
if ((xxxxxxxxxxxx).matches(".*"+pat+".*"))
{
return item;
}
}
}
The above code is part of a class from my java program
public class Item
{
private String title;
private int playingTime;
private boolean gotIt;
private String comment;
/**
* Initialise the fields of the item.
*/
public Item(String theTitle, int time)
{
title = theTitle;
playingTime = time;
gotIt = true;
comment = "";
}
public String getTitle() {
return title;
}
/**
* Enter a comment for this item.
*/
public void setComment(String comment)
{
this.comment = comment;
}
/**
* Return the comment for this item.
*/
public String getComment()
{
return comment;
}
/**
* Set the flag indicating whether we own this item.
*/
public void setOwn(boolean ownIt)
{
gotIt = ownIt;
}
/**
* Return information whether we own a copy of this item.
*/
public boolean getOwn()
{
return gotIt;
}
public int getPlayingTime()
{
return playingTime;
}
/**
* Print details about this item to the text terminal.
*/
public void print()
{
System.out.println("Title: " + title);
if(gotIt) {
System.out.println("Got it: Yes");
} else {
System.out.println("Got it: No");
}
System.out.println("Playing time: " + playingTime);
System.out.println("Comment: " + comment);
}
}
I want to access all the methods that return values from class Item and once it matches the statement in Item searchByPattern, it will return the object.
I knew that I can do it by or operator like item.getTitle().matches(".*"+pat+".*") ||item.getComment().matches(".*"+pat+".*")||.......
but is it possible to get the same result by using a method in (xxxxxxxxxx)?
This isn't directly possible to do, however there are a few things you can try (from easiest to hard):
Just check all String type methods yourself in your code.
Add a special method in Item that does the match so Item class can decide itself when it matches. Here again you will need to make check all Strings manually.
You could add a method to Item that returns all methods that return a String as functions:
Code:
List<Supplier<String>> getAllStringMethods() {
return Arrays.asList(this::getComment, this::getTitle);
}
You can then use that to check all Strings one at a time by doing:
boolean match = item.getAllStrings().stream()
.map(Supplier::get)
.anyMatch(s -> s.matches("pattern"));
You can use Reflection to inspect the Item.class to find all methods that take no parameters and return a String, and then invoke them one by one. This is complicated and slow, and beyond the scope of this answer to explain further.

HashMap Issuses

Edited the getTypeString method in the Flowers class now I just get the pointer to the object
I'm working on a project for one of my classes. I haven't worked with HashMap before and I need to use one. In this java class I'm trying to print out the full description that I have set. But it wont print the HashMap value from the key. I have tried to use some code from my book, but with no luck.
This is the class that is calling the class that has the HashMap:
public class Garden
{
private Gardener gardener;
private Tools tools;
private Flowers flowers;
/**
* Constructor for objects of class Garden
*/
public Garden()
{
gardener = new Gardener();
tools = new Tools();
Flowers rose;
rose = new Flowers("a beautiful red flower");
rose.setFlower("red", rose);
System.out.println(rose.fullDescription());
}
}
Edited the getTypeString method
This is the class that is using the HashMap:
import java.util.Set;
import java.util.HashMap;
public class Flowers
{
private String fDescription;
private HashMap<String, Flowers> flowers;
/**
* Constructor for objects of class Flowers
*/
public Flowers(String fDescription)
{
this.fDescription = fDescription;
flowers = new HashMap<String, Flowers>();
}
public void setFlower(String color, Flowers type)
{
flowers.put(color, type);
}
public String flowerDescription()
{
return fDescription;
}
public String fullDescription()
{
return "The "+ getTypeString() + " is " + fDescription;
}
private String getTypeString()
{
String des = "";
Collection<Flowers> vals = flowers.values();
for(Flowers f : vals){
des += f;
}
return des;
}
}
The problem, I think, is in the getTypeString() function. Can anyone point me in the right direction?
Edit
I removed the getTypeString method and edited the fullDescription method:
public String fullDescription()
{
return "The "+ type + " is " + fDescription;
}
now I'm trying to get the 'HashMap' to print the objects like so:
"Flower [type= type, description= Description "]"
using thes methods:
public static void printHashMap()
{
System.out.println("hashmap: " + flowers);
}
#Override
public String toString()
{
return "Flower [type=" + type + ", description=" + fDescription ]";
}
From your post, what I have understood is that you want to print the description of flowers. So I think you can try something like:
private String getTypeString(){
String des = "";
Collection<String> vals = flowers.values();
for(String f : vals){
des = des + f.flowerDescription();
}
return des;
}
Override the toString method in your class
Declare a toString method with the following modifiers and return type:
#Override
public String toString() {
return this.fDescription;
}
Implement the method so that it returns a string.

getting "cannot make a static reference to the non-static method" error, but I haven't declared the method I'm calling from as static

When I try compile I'm getting the error:
cannot make a static reference to the non-static method getId() from the type Doctor.
Doctor is a sub-class of Staff. I get the same error when I replace Doctor with Staff in the code. I understand that I can't substitute a super-class for a sub-class so that's why Staff wont work, but in my Database class, I haven't declared anything as static so I don't understand why or how it is static and why I'm getting that error.
This is my database class
import java.util.ArrayList;
public class Database
{
String id;
private ArrayList<Staff> staff;
/**
* Construct an empty Database.
*/
public Database()
{
staff = new ArrayList<Staff>();
}
/**
* Add an item to the database.
* #param theItem The item to be added.
*/
public void addStaff(Staff staffMember)
{
staff.add(staffMember);
}
/**
* Print a list of all currently stored items to the
* text terminal.
*/
public void list()
{
for(Staff s : staff) {
s.print();
System.out.println(); // empty line between items
}
}
public void printStaff()
{
for(Staff s : staff){
id = Doctor.getId();//This is where I'm getting the error.
if(true)
{
s.print();
}
}
}
This is my Staff class.
public class Staff
{
private String name;
private int staffNumber;
private String office;
private String id;
/**
* Initialise the fields of the item.
* #param theName The name of this member of staff.
* #param theStaffNumber The number of this member of staff.
* #param theOffice The office of this member of staff.
*/
public Staff(String staffId, String theName, int theStaffNumber, String theOffice)
{
id = staffId;
name = theName;
staffNumber = theStaffNumber;
office = theOffice;
}
public String getId()
{
return this.id;
}
/**
* Print details about this member of staff to the text terminal.
*/
public void print()
{
System.out.println("ID: " + id);
System.out.println("Name: " + name);
System.out.println("Staff Number: " + staffNumber);
System.out.println("Office: " + office);
}
}
You're calling the method as if it's static, since you're calling it using the class name: Doctor.getId().
You'll need an instance of the class Doctor to call the instance methods.
Perhaps you intend to call getId on the s (instance of Staff) in the loop?

Java compareTo (Object obj)

I've given an assigment and its the last day of itself. I did most of it but on the last question I have a problem with creating a compareTo() function.
Here is what it does want from us ;
compareTo
public int compareTo(java.lang.Object other)
Specified by:
compareTo in interface java.lang.Comparable
Here is what I did
public int compareTo(Object obj)
{
Document tmp = (Document)obj;
if(this.text < tmp.text)
{
/* instance lt received */
return -1;
}
else if(this.text > tmp.text)
{
/* instance gt received */
return 1;
}
/* instance == received */
return 0;
}
Here is my whole Document.java file
class Document
{
private String text;
/**
* Default constructor; Initialize amount to zero.
*/
public Document()
{
text = "";
}
/**
* Default constructor; Initialize text to input value
* #param text New text value
*/
public Document(String text)
{
this.text = text;
}
/**
* Returns as a string the contents of the Document.
*/
public String toString()
{
return text;
}
and Here is the test file of itself.
import java.util.Arrays;
public class Homework2 extends Document {
/** ======================
* ContainsKeyword
* Returns true if the Document
* object passed in contains keyword as a substring
* of its text property.
* ======================
*/
public static boolean ContainsKeyword(Document docObject, String keyword)
{
if (docObject.toString().indexOf(keyword,0) >= 0)
return true;
return false;
}
public static void main(String[] args){
Email email1= new Email("Programming in Java",
"Larry", "Curly", "Programming");
Email email2 = new Email("Running marathons",
"Speedy", "Gonzales", "races");
System.out.println(email1);
File file1 = new File("Some Java file", "file.txt");
File file2 = new File(
"Boluspor wins against Besiktas. Muahahahaha",
"bolutas.txt");
Document doc = new Document (
"ok?,ok?,ok?,ok?,ok?,ok?,ok?,ok?,ok?,ok?,ok?,ok?");
System.out.println("\n"+file1);
System.out.println("\nWhich contains Java?");
if (ContainsKeyword(email1,"Java")) System.out.println(" Email1");
if (ContainsKeyword(email2,"Java")) System.out.println(" Email2");
if (ContainsKeyword(file1,"Java")) System.out.println(" File1");
if (ContainsKeyword(file2,"Java")) System.out.println(" File2");
Document [] da = new Document [5];
da[0] = email1;
da[1] = email2;
da[2] = file1;
da[3] = file2;
da[4] = doc;
Arrays.sort(da);
System.out.println("\nAfter sort:");
for(Document d : da){
System.out.println(d);
}
}
}
What I wanted to ask is, I cannot compare the objects from my Email.java and File.java , I can do anything else but the last part which starts with Document [] da... That part gives an error. What am I doing wrong here?
The error is ;
Exception in thread "main" java.lang.ClassCastException: Email cannot be cast to java.lang.Comparable
at java.util.Arrays.mergeSort(Arrays.java:1144)
at java.util.Arrays.sort(Arrays.java:1079)
at Homework2.main(Homework2.java:53)
UPLOAD ** Here is my Email and File Class..
/**
* First define class for Email, derive from Document
*/
class Email extends Document
{
private String sender;
private String recipient;
private String title;
private String body;
/**
* Constructors
*/
public Email()
{
super();
sender = "";
recipient = "";
title = "";
body = "";
}
public Email(String body, String sender, String recipient, String title)
{
this.sender = sender;
this.recipient = recipient;
this.title = title;
this.body = body;
}
// ======================
// Various accessor and mutator methods
// ======================
public String getSender()
{
return sender;
}
public void setSender(String sender)
{
this.sender = sender;
}
public String getRecipient()
{
return recipient;
}
public void setRecipient(String recipient)
{
this.recipient = recipient;
}
public String getTitle()
{
return title;
}
public void setTitle(String title)
{
this.title = title;
}
public String getBody(){
return body;
}
public void getBody(String body){
this.body = body;
}
/**
* Returns as a string the contents of the text fields concatenated
* together. Uses super.toString to get the parent's text.
*/
public String toString()
{
return "Sender:" + sender + ",Recipient:" + recipient + ",Title:" + title + ",Body:" + body + " " +
super.toString();
}
} // Email
and File ;
/**
* Next define class for File, derive from Document
* For brevity, short one-line methods are defined here in the
* header.
*/
class File extends Document
{
private String pathname;
/**
* Constructors.
*/
public File()
{
super();
pathname = "";
}
public File(String body, String pathname)
{
super(body);
this.pathname = pathname;
}
// ======================
// Various accessor and mutator methods
// ======================
public void setPathname(String s)
{
pathname = s;
}
public String getPathname()
{
return pathname;
}
/**
* Returns as a string the contents of the text fields concatenated
* together. Uses super.toString to get the parent's text.
*/
public String toString()
{
return "Pathname " + pathname + " Body " + super.toString();
}
} // File
Where did you put the compareTo method? If you're trying to sort an array of Documents, you need to have Document implement Comparable (or pass in a Comparator):
public class Document implements Comparable<Document> {
Or, if for some bizarre reason you're not allowed to use generics:
public class Document implements Comparable {
Then put compareTo within Document.
The exact reason it is failing is because you are trying to call Arrays.sort on a class that does not implement comparable
Implementing Comparable allows
calling Collections.sort and Collections.binarySearch
calling Arrays.sort and Arrays.binarySearch
using objects as keys in a TreeMap
using objects as elements in a TreeSet
Email did not implement the Comparable interface
use
public class Email implements Comparable<Email>
read this to do yourself a favor http://www.javapractices.com/topic/TopicAction.do?Id=10
The other note is you said you want to compare
Email.java and File.java
You will need a custom function for that based on the logic.
compareTo is used to compare two instances of the same type. It also means that the function lives in the Email class
Email myEmail = new Email();
Email hisEmail = new Email();
myEmail.compareTo(hisEmail);
What you are doing wrong is in the error message.
You can only sort objects for classes which implement Comparable. Your class does not.
As you are sorting a number of different types you may want to provide a custom Comparator instead, or make Document implement Comparable.
try this:
Here is my whole Document.java file
class Document implements Comparable { //this line is your solution.
private String text;
/**
* Default constructor; Initialize amount to zero.
*/
public Document()
{
text = "";
}
/**
* Default constructor; Initialize text to input value
* #param text New text value
*/
....}

Categories

Resources