Java, singleton elements modification, software patterns - java

short question. Hopefully it gets answered pretty fast. Lets say I have a singleton like this:
package main.library;
public enum LibrarySingleton {
INSTANCE(new String[][]{});
final String[][] bookStore;
private LibrarySingleton(String[][] bookStore){
this.bookStore = bookStore;
}
}
and a Book class that holds 3 variables:
package main.library;
public class Book{
String author;
String title;
int pages;
#Override public String toString(){
return ("|" + author + "|" + title + "|" + pages + "|");
}
public Book(){
System.out.println("Error: No book information specified");
}
public Book(String author, String title, int pages){
this.author = author;
this.title = title;
this.pages = pages;
}
public String getAuthor(){
return author;
}
public String getTitle(){
return title;
}
public int getPages(){
return pages;
}
}
I'm looking on how to use that singleton as an array holding books. How can I access the books, throw them into the array (singleton), or remove them from the array (singleton)? In case the singleton should be written differently, please correct me, and explain why is it wrong, as I'm not so "premium" with Java yet.
Really hope you guys are going to answer me on that. Just the questions please.

If you want singleton, you can use following approach:
public class Library {
private static final Library instance = new Library();
private List<Book> books = new ArrayList<Book>();
public static Library getInstance() {
return instance ;
}
public void add(Book book) {
books.add(book);
}
}
Of course, add synchronization if your program has multiple threads. And if your program runs in J2EE environment, where complex classloading occurs, you need a different pattern.

If you initialize an empty array and make it final it will stay empty and you cannot reinitialize it. I guess what you need is an arraylist (list in general). That one you can initialize and add element to it.

Related

Why doesn't my get method getAuthor() return output?

My BookTester class is creating a new book and calling getAuthor(), but when I run, it doesn't return any output. I'm not sure why? Any help is appreciated, thanks!
public class BookTester {
public static void main(String[] args) {
Book myBook = new Book("My life", "Sam Daily", 2001);
myBook.getAuthor();
}
}
class Book {
private String title;
private String author;
private int publishedYear;
public Book(String title, String author, int year)
{
this.title = title;
this.author = author;
publishedYear = year;
}
public int getYear(){
System.out.println(publishedYear);
return publishedYear;
}
public String getTitle(){
return title;
}
public String getAuthor(){
return author;
}
}
The method signature:
public String getAuthor(){ ... }
represents a method that takes no parameters and returns a String. even the name of the method speaks it "getAuthor", to get or retrieve something.
and you're ignoring the result of the method call.
the solution is either store the result to a variable and then operate on it.
String author = myBook.getAuthor();
or if you want to print to the console then you can do:
System.out.println(myBook.getAuthor());
Reason why you don't see returned value is because you are ignoring it.
public static void main(String[] args) {
Book myBook = new Book("My life", "Sam Daily", 2001);
myBook.getAuthor(); // Value is returned but not used
}
Instead you could assign returned value to variable and print it or just print it from method call:
System.out.println(myBook.getAuthor());
Considering that this is really basic thing I suggest you to get some good Java book or some tutorial in other to advance faster.
The method getAuthor() effectivly returns something, but you did not use it
You can store it to use after :
String author = myBook.getAuthor();
System.out.println(author); // for simple printing
System.out.println(author.charAt(1)); // to print a single char
...
You can print it directly
System.out.println("The author is "+ myBook.getAuthor());
First receive method result in string variable and print it..
string result=myBook.getAuthor();
system.out.println(result);

How to change array to an object class?

I have cut out the code to shorten the page but I'm asking how do I change personInterests into its own class. Apologies for the vague question but essentially I want to change personInterests in my Person class to a class where personInterests has multiple variables.
import java.util.ArrayList;
import java.util.*;
public class Person{
private String personName;
private String[] personInterests = new String[3];
public Person(String personName, String[] personInterests){
this.personName = personName;
this.personInterests = personInterests;
}
public void setInterests(String[] personInterests){
this.personInterests = personInterests;
}
public String[] getInterests(){
return personInterests;
}
public String getName(){
return personName;
}
public String toString(){
String result = getName() + " ";
for (String interests : personInterests) {
result += interests + " ";
}
return result;
}
}
This was my idea of how it would work just not sure how I would use this class and call it later on.
import java.util.ArrayList;
import java.util.*;
public class Interests {
private int interestDangerRating;
private String interestName;
private ArrayList<Interests> interestsList = new ArrayList<>();
public Interests (int interestDangerRating ,String interestName){
this.interestDangerRating = interestDangerRating;
this.interestName = interestName;
}
public void addInterests(Interests p){
interestsList.add(p);
}
Interests getInterests(int i){
return interestsList.get(i);
}
}
Any help is appreciated, as I said this code has mostly been taken out and this was an old project already completed just wanted to see if I could change some of the features.
OK so here's what I would do to clean this up for you and make it work. Firstly, think about what you are trying to do. You want to create a Person who has multiple Interests, right? So the Interest class, going by your above example, can be changed to be a typical Java object class as follows:
public class Interest {
private int dangerRating;
private String name;
public Interest (int dangerRating, String name) {
this.dangerRating = dangerRating;
this.name = name;
}
public int getDangerRating() {
return dangerRating;
}
public String getName() {
return name;
}
}
So now we've an Interest class set up where you can set a name for your interest and a danger rating. What we need to do, now, is edit your Person class so as you can store a list of interests for each Person you create.
import java.util.ArrayList;
public class Person{
private String name;
private ArrayList<Interest> interests = new ArrayList<Interest>();
public Person(String name, ArrayList<Interest> interests) {
this.name = name;
this.interests = interests;
}
public void addInterest(Interest newInterest) {
interests.add(newInterest);
}
public Interest getInterest(int indexOfInterest) {
return interests.get(indexOfInterest);
}
public ArrayList<Interest> getInterests() {
return interests;
}
public String getName() {
return name;
}
public String toString() {
String result = getName() + " ";
for(Interest interest : interests) {
result += interest.getName() + "(" + interest.getDangerRating() + ")" + " ";
}
return result.trim();
}
}
This allows you to set an initial list of all interests for your new Person and, from there, you can add new interests, get all interests or get any individual interest.
Hope this helps to clarify for you how this should all fit together!
So now it's time to instantiate everything. Lets create some Interestobjects which we will use:
Interest golf = new Interest(1, "golf");
Interest swimming = new Interest(3, "swimming");
Now lets assume we want two people called John and Mary. John likes golf and swimming while Mary only likes swimming. We'd then create their list of Interest as follows:
ArrayList<Interest> johnsInterests = new ArrayList<Interest>();
johnsInterests.add(golf);
johnsInterests.add(swimming);
ArrayList<Interest> marysInterests = new ArrayList<Interest>();
marysInterests.add(swimming);
And finally, we'd then create our two Person objects which will include the persons name and interests list.
Person john = new Person("John", johnsInterests);
Person mary = new Person("Mary", marysInterests);
And voila!
First, make an Interestclass:
public class Interest {
private int interestDangerRating;
private String interestName;
// .. getters and setters
}
then in the Personclass get rid of private String[] personInterests = new String[3];
and replace it by:
private ArrayList<Interest> interestsList = new ArrayList<>();
You're getting there with the logic of your Interests class, but it needs a few changes
import java.util.ArrayList;
import java.util.*;
public class Interests {
private int interestDangerRating;
// Is this a unique name for the entire class? If yes then no worries, but if not
// then its not needed, you've already got a list of interest names below
private String interestName;
// Change the array list to hold Strings, it's a list of words
private ArrayList<String> interestsList = new ArrayList<>();
public Interests (int interestDangerRating ,String interestName){
this.interestDangerRating = interestDangerRating;
this.interestName = interestName;
}
public void addInterest(String p){ // Again, change this to String
interestsList.add(p);
}
String getInterest(int i){ // Change this to return a String, since we changed the ArrayList above
return interestsList.get(i);
}
}
There's alot more you need to think about with this class too. How do you know how many interests are in the list, should there be a length variable? Or what about a method that returns the entire list of interests rather than just 1?
Also, there's only one interestDangerRating being set in this class; if each interest has a different danger rating, should't you be adding a danger rating for every interest?
In terms of accessing your new class, you'll need to create a class in your code by:
Interests variableName = new Interests(1, "football");
I have randomly chosen '1' and 'football' above, since they are in your Interest class' constructor. The way your class is built, you cannot use it without providing an int and a String when the object is made
Finally, to call methods on your class, you use the variable created above to call its methods:
variableName.addInterest("basketball");
String interest = variableName.getInterest(1);
If you're struggling, I recommend looking at a simple java tutorial online. instatiating java classes and calling their methods like this are fundamental concepts in Java :)

Setting of an array or array list of object

I'm fairly new to coding so just wondering if someone can point me in the right direction. I'm looking to set up a Library class containing an array or array list of Book objects that carry out appropriate functions such as adding a Book, editing a Books details, deleting a Book, returning a Book and loaning a Book.
So far I have created the following Book class
//Instance variables
private int BookID;
private String Title;
private String Author;
private boolean On_Loan;
private int Number_of_Loans;
//Constructor
public Book(int BookID, String Title, String Author, boolean On_Loan, int Number_of_Loans){
this.BookID = BookID;
this.Title = Title;
this.Author = Author;
this.On_Loan = On_Loan;
this.Number_of_Loans = Number_of_Loans;
}
//Mutator methods
public void setBookID(int BookID){
this.BookID = BookID;
}
public void setTitle(String Title){
this.Title = Title;
}
public void setAuthor(String Author){
this.Author = Author;
}
public void setOn_Loan(boolean On_Loan){
this.On_Loan = On_Loan;
}
public void setNumber_of_Loans(int Number_of_Loans){
this.Number_of_Loans = Number_of_Loans;
}
//Accessor methods
public int getBookID(){
return BookID;
}
public String getTitle(){
return Title;
}
public String getAuthor(){
return Author;
}
public boolean getOn_Loan(){
return On_Loan;
}
public int getNumber_of_Loans(){
return Number_of_Loans;
}
}
You need an ArrayList<Book> object! To create one:
ArrayList<Book> books = new ArrayList<> ();
To add an item to it,
books.add (yourBookObjectToBeAdded);
To change the books' properties, you need to get the book first,
books.get(theIndexOfTheBook);
It is recommended to store the book in a variable:
Book myBook = books.get(theIndexOfTheBook);
And then you can use one of the mutators (setters),
myBook.setOn_Loan (true);
Advantages:
unlike arrays, ArrayList is dynamic in size.
It is generic, you don't need to cast stuff.
And that is basically a guide to using array lists. Now you want to make a class that do all this stuff. So it must contain an ArrayList<Book>:
public class Library {
private ArrayList<Book> books
public Library () {
books = new ArrayList<> ();
}
public ArrayList<Book> getBooks () {
return books;
}
}
Then the user can get the books and do operations on the array list.
Alternatively, you can make it more abstract. You can add borrowBook, returnBook, editBook and other methods to the class. For example, the borrowBook method would be like this:
public void borrowBook (int bookIndex) {
Book book = books.get(bookIndex);
book.setOn_Loan (true);
}
first, you will have to create the Book object
then you can create an array of Book objects like this
Book[] books = new Book[10]; //fixed list of size 10
Book b1 = new Book(); // create a book object
books[0] = b1; // assign it to be the first array element
or an arraylist list like this
ArrayList<Book> books = new ArrayList<Book>(); //initial empty list, no fixed size
Book b1 = new Book(); // create a book object
books.add(b1); // append it to the list
If their is a variable number of books, using an ArrayList will be a good choice, as you can add more books on the fly, unlike an array, where you have to fix the size.
To create an ArrayList of Book objects, use: ArrayList<Book> books = new ArrayList<Book>();
To add a book to the list: books.add(new Book());
To perform a command on a book (i.e. edit the details), you need to know the index of the book, or you could go through all of them. You can do this using the .get(index) command, for example:
books.get(index).doSomething();
You can read more about ArrayLists and all of their methods here, and a simple tutorial could be found here.

Objects not returning what I think it should be

OK, so we had to create like a bookshelf and book objects with publisher, author, copyright date, etc. on a seperate file (basically creating an object for a driver class). I've redone this twice now this week and still get the same error. Perhaps someone could point me in the right direction? Maybe I'm missing something, I'm not sure. EDIT: the problem is: sorry I'm getting ready for work and going ahead of myself I have three: first the output is giving me: Book#15db9742 Book#6d06d69c then the book class for the year is red saying to convert from a string to an int so I do then it wants to go back the other way
public class Book {
private String title;
private String author;
private String publisher;
private int copyDate;
public Book(String bookTitle, String authorName, String publisherName, int bookYear){
title = bookTitle;
author = authorName;
publisher = publisherName;
copyDate = bookYear;
}
public Book(){
title = "book titler";
author = "author name";
publisher = "book publisher";
copyDate = "2014";
}
public String getTitle() {
return title;
}
public void setTitle(String bookTitle) {
title=bookTitle;
}
public String getAuthor() {
return author;
}
public void setAuthor(String authorName) {
author = authorName;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisherName) {
publisher = publisherName;
}
public int getCopyDate() {
return copyDate;
}
public void setCopyDate(int copyDate) {
this.copyDate = copyDate;
}
}
Here is the main class:
public class BookShelf {
public static void main(String[] args) {
int bookYear = 2014;
Book name1 = new Book("book\n", "something\n", "something else\n", bookYear);
Book name2 = new Book("anotherBook\n", "anotherSomething\n", "somethingElse^2\n", bookYear);
System.out.println(name1);
System.out.println(name2);
}
}
I entered arbitrary information so I can make sure it works before I go searching for a good book to enter the information for lol.
Thank you!
I think you need to override the toString() method so System.out.println() prints the information you want about a book object.
By default Object's toString() doesn't print any fields but instead:
The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:
How to use the toString method in Java?
This method would go in the class (each class has it's own `toString() implementation)
class Book{
...
#Override
public String toString(){
//feel free to change this sting to whatever you want
return "Book " + title;
}
}
Also as Andreas Jabusch in the other answer, your constructor sets copyDate incorrectly. It should be an int
copyDate = 2014
Get rid of the quotes which makes it a String.
Your
copyDate = "2014"
has to be
copyDate = 2014
it's an int, not a String.

Set and HashSet Java

I'm relatively new to the Java language and have a project I'm doing for school in which I have a Book class that has the normal setters/getters, constructors, and overrides for this class, nothing complicated. I have to change it so I can get multiple authors by utilizing Set and HashSet. The question I have is how would I go about doing this? So far, and correct me if I'm wrong, I have this
import java.util.*;
public class Book{
private Set<String> authorSet;
private String isbn;
public Book(){
authorSet = null;
isbn = null;
}
public Book(String isbn, Set<String> authorSet){
this.isbn = isbn;
Set<String> s = new HashSet<String>();
// Do I do anything else here?
}
public String getIsbn(){
return isbn;
}
public void setIsnb(String isbn){
this.isbn = isbn;
}
public Set<String> getAuthorSet(Set<String> newAuthorSet{
return newAuthorSet;
}
public void setAuthorSet(Set<String> newAuthorSet){
this.authorSet = newAuthorSet;
}
Before moving on to the overrides, I want to make sure I get this properly. I've tried to look for similar examples so I can see what's going on, but I haven't had much luck as of yet. I'm sure it's very simple, but I'm just starting to learn the language. Thanks for the help
First of all, in your default constructor, get rid of
authorSet = null;
and instead initialize your authorSet variable to a new HashSet. The reason for this is that you want to create the authorSet container regardless of whether any authors are added to begin with.
You'll probably want a constructor that takes just an isbn String. Also consider a constructor that takes isbn String and a variable number of Author Strings.
Ah, I missed this:
public Book(String isbn, Set<String> authorSet){
this.isbn = isbn;
Set<String> s = new HashSet<String>();
// Do I do anything else here?
}
Not good as you ignore both the parameter and the field! Instead, assign the set parameter to the existing field as you would with any other field.
public Book(String isbn, Set<String> authorSet){
this.isbn = isbn;
this.authorSet = authorSet;
}
Then give your class an addAuthor(String author) method. Better for you to code this since this is homework. I really don't think that there's a whole lot more that you need with regards to this problem.
I'd have taken away the default constructor. Also, why would you need to set the authorSet? Wouldn't it better to just add and remove from it? Also why would you need to set the isbn. Could you instead just take it in the constructor, as I don't think you'd ever have to change it. How about something like this?
import java.util.HashSet;
import java.util.Set;
public class Book {
private final Set<String> authorSet;
private final String isbn;
public Book(String isbn) {
this.isbn = isbn;
this.authorSet = new HashSet<>();
}
public String getIsbn() {
return isbn;
}
public Set<String> getAuthorSet() {
return authorSet;
}
public void addAuthor(String author) {
authorSet.add(author);
}
public void removeAuthor(String author) {
authorSet.remove(author);
}
}
For extra points, the practice of returning your actual collection (set) implementation can allow a caller to muck with your internals. Thus, this is a little hazardous:
public Set<String> getAuthorSet() {
return authorSet;
}
safer:
public Set<String> getAuthorSet() {
return Collections.unmodifiableSet(authorSet);
}
Similarly if you had need to accept a new set in your API, but did not want to trust the caller to not later violate your representation, then you might do this:
public void setAuthorSet(Set<String> newAuthorSet) {
authorSet = new HashSet<String>(newAuthorSet);
}

Categories