Can the built in HashTable class show previous and next keys? - java

I am trying to write an ADT for a class that incorporates a sequence when there is a small amount of data to store (<1000 key values) and uses a HashTable otherwise. I have to write the sequence class myself but i was delighted to find out that java has it's own built in HashTable class. However, one of the requirements for this ADT is that it must be able to display the previous and next keys (called VINs in the code). I can do this easily with my sequence class, however I was wondering if the built in HashTable class had such a function. Will I have to write my own HashTable class or is there a way I can achieve my goal without having to do so? Thank you all for your help in advance, I really appreciate it!
This is the CVR class (data is passed to this class and it calls upon the sequence or HastTable class)
import java.util.*;
public class CVR
{
//this will be used to generate random alpha numeric numbers
private final static String alphaNumeric="ABDCEFGHIJKLMNOPQRSTUVWXYZ0123456789";
//key
private String VIN;
//threshold (determines which ADT to use)
private int threshold;
//length of key
private int VINLength;
//this is an object of Archive which will hold the data associated with VIN
private Account value;
//TBD
//private Collection<Account> activeVINS;
//HashMap to store all the key-value pairs
//the value come in the form of a stack because,
//multiple events can be associated with the same
//VIN, and must be shown in reverse-chronological order
private Hashtable<String, Stack<Account>> hashRecords;
private sequence seqRecords;
//This will keep track of all VINs and make sure
//none of them are repeated
private HashSet<String> VINRecorder;
private boolean hashTabl=false;
//default constructor
public CVR(int threshold) throws Exception
{
this.setThreshold(threshold);
if (threshold>1000)
{
hashRecords=new Hashtable<>();
hashTabl=true;
}
else
{
seqRecords=new sequence();
hashTabl=false;
}
}
//not sure this is even needed
//parameterized constructor for CVR, takes VIN
//and adds it to VINRecorder
//re-evaluate this method, with this a VIN is added to HashSet, but not to
//HashMap. At the same time I'm not sure We want VINs w/o associated accounts
//to be in HashMap. TBD
//For now actually, I will add them to HashMap, this may change down the line...
/**
public CVR (String VIN) throws Exception
{
this.VIN=VIN;
records=new Hashtable<>();
VINRecorder=new HashSet<>();
add(VIN, null);
//Stack<Account> stack = new Stack<Account>();
//VINRecorder.add(VIN);
}
**/
//accessors and mutators
//VIN getters and setters
public String getVIN()
{
return VIN;
}
public void setVIN(String VIN)
{
this.VIN=VIN;
VINRecorder=new HashSet<>();
VINRecorder.add(VIN);
}
//threshold getters and setters
public int getThreshold()
{
return threshold;
}
//for this one we have to keep in mind the restriction set
//on us in the instructions
public void setThreshold(int threshold) throws Exception
{
if(threshold<100 || threshold>900000)
{
//System.out.println("Invalid input for threshold");
throw new Exception("Invalid input for threshold");
}
else
{
this.threshold=threshold;
}
}
//VINLength getters and setters
public int getVINLength()
{
return VINLength;
}
//again for this one. we need to take the
//instructions into account for this special
//case
public void setVINLength(int VINLength) throws Exception
{
if(VINLength<10 || VINLength>17)
{
throw new Exception("Invalid input for VIN length");
}
else
{
this.VINLength=VINLength;
}
}
//Now onto the methods
//Generate method
//This method should randomly generate a sequence
//containing n new non-existing valid keys
//***Must determine whether the output is a sequence or not
public String generate(int size) throws Exception
{
char[] Arr= alphaNumeric.toCharArray();
String[] ender=new String[size];
//generating random number between 10 and 17
Random r= new Random();
int low=10;
int high=17;
for(int x=0; x<size;x++)
{
int highLow=r.nextInt(high-low)+10;
StringBuilder newString=new StringBuilder();
//making string between length of 10 and 17 randomly
for(int i=0; i<highLow; i++)
{
newString.append(Arr[new Random().nextInt(Arr.length)]);
}
///////////////////
String newVIN=newString.toString();
//System.out.println(newVIN);
//This must be further explored, I do not know why,
//but for some reason it does not work if the first
//condition is not there, to be explored
if(newVIN!=null)
{
}
//stops here for some reason, must find out why, something is wrong with this statement
else if(VINRecorder.contains(newVIN))
{
x--;
}
else
{
ender[x]=newString.toString();
}
ender[x]=newString.toString();
}
//System.out.println("hello");
System.out.println(Arrays.toString(ender));
return Arrays.toString(ender);
}
//method allKeys
//this method should return all keys as a sorted
//sequence in lexicographic order
//the plan here is to use
/**
public LinkedList<Account> allKeys()
{
}
**/
//add method
//****must check to see if must be resized later
public void add(String VIN, Account value) throws Exception
{
if(hashTabl==true)
{
if(!VIN.equals(value.getVIN()))
{
System.out.println("Something went wrong :/");
throw new Exception("VIN does not match account");
}
else if(hashRecords.containsKey(VIN))
{
System.out.println("VIN exists, adding to record");
hashRecords.get(VIN).add(value);
System.out.println("Success!");
}
else
{
System.out.println("New account made, record added!");
Stack<Account> stack = new Stack<Account>();
stack.add(value);
hashRecords.put(VIN, stack);
System.out.println("Success!");
//resize here
//
}
}
else
{
if(value==null)
{
Account saveVIN=new Account(VIN);
seqRecords.add(saveVIN);
}
seqRecords.add(value);
}
}
//remove method
//***must check to see if must be resized later
public void remove(String VIN)
{
if(hashTabl==true)
{
if(hashRecords.containsKey(VIN))
{
hashRecords.remove(VIN);
//resize here
//
}
else
{
System.out.println("Key does not exist in HashTable");
}
}
else
{
seqRecords.removeVIN(VIN);
}
}
//getValues method
public Stack<Account> getValues(String VIN)
{
if(hashTabl == true)
{
if(hashRecords.containsKey(VIN))
{
Stack<Account> values = new Stack<Account>();
values=hashRecords.get(VIN);
return values;
}
else
{
System.out.println("This VIN could not be found in directory");
return null;
}
}
else
{
return seqRecords.getAccount(VIN);
}
}
//nextKey methods
public String nextVIN(String VIN)
{
//unfinished, not sure what to call here
if(hashTabl=true)
{
return hashRecords.
}
else
{
return seqRecords.nextVIN(VIN);
}
}
//previous Accidents method
public Stack<Account> prevAccids(String VIN)
{
if(hashTabl == true)
{
if(hashRecords.contains(VIN))
{
Stack<String> Accids= new Stack<String>();
Stack<Account> temp; //= new Stack<Account>();
temp=hashRecords.get(VIN);
return temp;
/**
String tempString;
while(!temp.isEmpty())
{
tempString=temp.pop().getAccids();
Accids.push(tempString);
}
temp=null;
return Accids;
**/
}
return null;
}
else
{
Stack<Account> temp;
temp=seqRecords.getAccount(VIN);
if(temp==null || temp.isEmpty())
{
System.out.println("This VIN does not exist in the sequence");
return null;
}
else
{
return temp;
}
}
}
//driver method
public static void main(String[] args) throws Exception
{
CVR hello= new CVR(100);
try
{
//System.out.println("hello");
//hello.generate(5);
Account abdcg=new Account("adsj4jandnj4", "Muhammad Ferreira", "perfect record");
Account abdcg1=new Account("adsj4jandnj4","Myriam Ferreira", "Fender Bender");
Account abdcg2= new Account("adsj4jandnj4", null, null);
/////
hello.add("adsj4jandnj4", abdcg);
hello.add("adsj4jandnj4", abdcg2);
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
This is my sequence class
import java.util.ArrayList;
import java.util.Stack;
public class sequence
{
private class position
{
private Stack<Account> stack;
private int index;
//constructors
public position()
{
this.stack=new Stack<Account>();
this.index=0;
}
public position(int index, Account acc)
{
this.index=index;
this.stack=new Stack<Account>();
stack.push(acc);
}
//muatators
public int getIndex()
{
return index;
}
public void setIndex(int index)
{
this.index=index;
}
public Stack<Account> getStack()
{
return stack;
}
public void setStack(Stack<Account> newStack)
{
this.stack=newStack;
}
}
private int size;
//private int tail;
private int elementsNum;
//private int currentIndex;
private ArrayList<position> Arr;
public sequence()
{
//currentIndex=0;
size=0;
Arr= new ArrayList<position>(); ;
}
//add first method
public void add(Account account)
{
for(int i=0; i<size; i++)
{
//if already in array, push into its stack
if((Arr.get(i).getStack().peek().getVIN()).equals(account.getVIN()))
{
Arr.get(i).getStack().push(account);
break;
}
//if not in array, make new entry for it
else if(!(Arr.get(i).getStack().peek().getVIN()).equals(account.getVIN()) && i==size-1)
{
position added=new position(size, account);
Arr.add(added);
//currentIndex++;
size++;
}
}
}
//addIndex
//don't think this method is necessary for assignment
/**
public void addIndex(int ind, Account account)
{
position added=new position(ind, account);
Arr.add(ind, added);
size++;
//update indexes of position node
updateIndex();
}
*/
//resizeArray and updates index
public void resize()
{
Arr.trimToSize();
updateIndex();
}
//remove method
public void removeVIN(String VIN)
{
for (int i=0; i<size; i++)
{
if(size==0 || (!VIN.equals(Arr.get(i).getStack().peek().getVIN()) && i==size-1))
{
System.out.println("The Sequence does not contain this VIN");
break;
}
else if(VIN.equals(Arr.get(i).getStack().peek().getVIN()))
{
Arr.remove(i);
resize();
size--;
System.out.println("Successfully removed " +VIN+" and associated values");
}
}
}
//update indexes
public void updateIndex()
{
for (int i=0; i<size; i++)
{
if(Arr.get(i).getIndex() != i)
{
Arr.get(i).setIndex(i);
}
}
}
//Get Values
//Will be used in CVR for both the getValues method (return all values)
//and prevAccids method (return only the accidents not entire account)
public Stack<Account> getAccount(String VIN)
{
for (int i=0; i<size; i++)
{
if(size==0)
{
System.out.println("The Sequence is empty");
break;
}
else if(VIN.equals(Arr.get(i).getStack().peek().getVIN()))
{
return Arr.get(i).getStack();
}
}
return null;
}
//get previous VIN method
public String preVIN(String VIN)
{
for (int i=0; i<size; i++)
{
if((Arr.get(i).getStack().peek().getVIN()).equals(VIN))
{
if(i==0)
{
return "There is no previous VIN, this is the first one";
}
return Arr.get(i-1).getStack().peek().getVIN();
}
}
return null;
}
//get next VIN method
public String nextVIN(String VIN)
{
for (int i=0; i<size; i++)
{
if((Arr.get(i).getStack().peek().getVIN()).equals(VIN))
{
if(i==size-1)
{
return "There is no next VIN, this is the last one";
}
return Arr.get(i+1).getStack().peek().getVIN();
}
}
return null;
}
}
Finally, this is my Account class
//this method is similar to a node, contains
//VIN, Owner, Accidents details
public class Account
{
private String VIN;
private String owner;
private String accidents;
public Account() {};
public Account(String VIN)
{
this.VIN=VIN;
this.owner=null;
this.accidents=null;
}
public Account(String VIN, String owner, String accidents)
{
this.VIN=VIN;
this.owner=owner;
this.accidents=accidents;
}
//mutators
public void setVIN(String VIN)
{
this.VIN=VIN;
}
public String getVIN()
{
return VIN;
}
public void setOwner(String owner)
{
this.owner=owner;
}
public String getOwner()
{
return owner;
}
public void setAccids(String accidents)
{
this.accidents=accidents;
}
public String getAccids()
{
return accidents;
}
}

You may want to use TreeMap instead of obsolete Hashtable - it is sorted by key by design and provides methods to get sequence of keys and related values:
K firstKey()
K lastKey()
K higherKey(K key)
K lowerKey(K key) etc.

Related

How to merge two alike items within the ArrayList?

So, I have 1 superclass DessertItem. Which has 4 subclasses Candy, Cookie, Ice Cream, Sundae. The Sundae class extends the Ice Cream class. Superclass is an abstract class. I also have a separate class which does not belong to the superclass, but in the same package - Order. There is another class - DessertShop, where the main is located.
Candy, Cookie classes implement SameItem<> generic class. The generic interface SameItem<> class looks like this:
public interface SameItem<T> {
public boolean isSameAs(T other);
}
The Candy, Cookie classes have this method:
#Override
public boolean isSameAs(Candy other) {
if(this.getName() == other.getName() && this.getPricePerPound() == other.getPricePerPound()) {
return true;
}
else {
return false;
}
}
And something similar, but for the cookie class.
All the subclasses have these methods :
default constructor,
public Cookie(String n, int q, double p) {
super(n);
super.setPackaging("Box");
cookieQty = q;
pricePerDozen = p;
}
public int getCookieQty() {
return cookieQty;
}
public double getPricePerDozen() {
return pricePerDozen;
}
public void setCookieQty(int q) {
cookieQty = q;
}
public void setToppingPricePricePerDozen(double p) {
pricePerDozen = p;
}
#Override
public double calculateCost() {
double cookieCost = cookieQty * (pricePerDozen/12);
return cookieCost;
}
and toString() method
So, what my program does is gets the input from the User, asks the name of the dessert, asks the quantity, or the quantity according to the dessert, ask the unit price. Asks the payment method. And then prints the receipt. This how the Order class looks like:
import java.util.ArrayList;
import java.util.List;
public class Order extends implements Payable{
//attributes
PayType payMethod;
private ArrayList<DessertItem> OrderArray;
//Constructor
public Order() {
OrderArray = new ArrayList<>();
payMethod = PayType.CASH;
}
//methods
public ArrayList<DessertItem> getOrderList(){
return OrderArray;
}// end of getOrderList
public ArrayList<DessertItem> Add(DessertItem addDesert){
enter code here
OrderArray.add(addDesert);
/* for(DessertItem i : getOrderList()) {
if(i instanceof Candy) {
for(DessertItem j : getOrderList()) {
if(j instanceof Candy) {
if(((Candy) i).isSameAs((Candy) j)) {
*/
//this is what I have tried so far, but I am lost
}
}
}
} else if(i instanceof Cookie) {
for (DessertItem j : getOrderList()) {
if(((Cookie) i).isSameAs((Cookie)j)) {
OrderArray.add(j);
} else {
OrderArray.add(i);
}
}
}
}
return OrderArray;
}// end of Add
public int itemCount(){
int counted = OrderArray.size();
return counted;
}//end of itemCount
public double orderCost() {
double orderResult = 0;
for(int i=0; i<OrderArray.size(); i++) {
orderResult = orderResult + OrderArray.get(i).calculateCost();
}
return orderResult;
}
public double orderTax() {
double taxResult = 0;
for(int i = 0; i<OrderArray.size(); i++) {
taxResult = taxResult + OrderArray.get(i).calculateTax();
}
return taxResult;
}
public double orderTotal() {
double ordertotal = orderTax() + orderCost();
return ordertotal;
}
#Override
public PayType getType() {
// TODO Auto-generated method stub
return payMethod;
}
#Override
public void setPayType(PayType p) {
payMethod = p;
}
public String toString() {
String finalOutput = "";
finalOutput += "------------------------Receipt--------------------------\n";
for(int i = 0; i < OrderArray.size(); i++) {
finalOutput = finalOutput + OrderArray.get(i).toString();
}
finalOutput += "--------------------------------------------------\n";
String line2 = "Total Number of items in order: " + itemCount() + "\n";
String line3 = String.format("Order Subtotals:\t\t\t\t $%-6.2f", orderCost());
String line4 = String.format("[Tax: $%.2f]\n", orderTax());
String line5 = String.format("\nOrder Total:\t\t\t\t\t $%-6.2f\n", orderTotal());
String outputVar = String.format("%s\n%s%s%17s", line2, line3, line4, line5);
String ending = "----------------------------------------------------";
String payType = String.format("\nPaid for with: %s", payMethod.name());
return finalOutput + outputVar + ending + payType;
}
So, my question is, how can I combine like items into one item?

Java linked List implementation won't add data

I created my own linked list in java(code below) and I was trying to store DNA?RNA sequences from a text file in an array of a custom data type that contains the enum DNA/RNA, as well as a linked list containing the actual DNA sequence. I don't know if the characters are just not being inserted into the linked list or if there is a problem with my toString but the output only prints the position and enum type, not the sequence from the list. Code is below
My node class
public class Node<E> {
private Node<E> next;
protected E data;
Node(E data,Node<E> nextVal){
this.data=data;
next=nextVal;
}
Node(Node<E> nextVal){
next=nextVal;
}
Node<E> Next(){
return next;
}
Node<E>setNext(Node<E> nextVal){
return next=nextVal;
}
E data(){
return data;
}
E setData(E it){
return data=it;
}
}
My Linked List Class
public class MyLinkedList<E> implements List<E>{
private Node<E> head;
private Node<E> tail;
protected Node<E> curr;
private int size;
MyLinkedList(int size){
this();
}
MyLinkedList(){
curr=tail=head=new Node<E>(null);
size=0;
}
#Override
public void clear() {
head.setNext(null);
curr=tail=head=new Node<E>(null);
size=0;
}
#Override
public void insert(E item) {
curr.setNext(new Node<E>(item, curr.Next()));
if(tail==curr)
tail=curr.Next();
size++;
}
#Override
public void append(E item) {
tail=tail.setNext(new Node<E>(item, null));
size++;
}
#Override
public E remove() {
if(curr.Next() ==null)
return null;
E item=curr.Next().data();
if(tail==curr.Next())
tail=curr;
curr.setNext(curr.Next().Next());
size--;
return item;
}
#Override
public void moveToStart() {
curr =head;
}
#Override
public void moveToEnd() {
curr=tail;
}
#Override
public void prev() {
if(curr==head)
return;
Node<E> temp=head;
while (temp.Next()!=curr)
temp=temp.Next();
curr=temp;
}
#Override
public void next() {
if(curr!=tail)
curr=curr.Next();
}
#Override
public int length() {
return size;
}
#Override
public int currPos() {
Node<E>temp=head;
int i;
for(i=0;curr!=temp;i++)
temp.Next();
return i;
}
#Override
public void moveToPos(int pos) {
assert (pos>=0)&& (pos<=size):
"Position out of Range";
curr=head;
for(int i=0;i<pos;i++)
curr.Next();
}
#Override
public E getValue() {
if(curr.Next()==null)
return null;
return curr.Next().data();
}
#Override
public String toString() {
String result = "";
Node current = head;
while(current.Next() != null){
result += current.data();
if(current.Next() != null){
result += ", ";
}
current = current.Next();
}
return "" + result;
}
}
This is the SequenceArr class which handles the operations on the array mentioned above (not complete here but all that is used in this example)
public class SequenceArr {
private TypeSeq [] SeqArr;
private int size=0;
private int MAXSIZE;
public SequenceArr(int MAXSIZE){
this.MAXSIZE=MAXSIZE;
SeqArr =new TypeSeq[MAXSIZE];
size=0;
}
public void insert(int pos, Type t, MyLinkedList<Character> seq){
TypeSeq currentEl=new TypeSeq(t,seq);
assert pos<=MAXSIZE: "Position over maximum size of array";
SeqArr[size]=currentEl;
size++;
}
public void remove(int pos){
if(SeqArr[pos]!=null){
while(SeqArr[pos+1]!=null){
SeqArr[pos]=SeqArr[pos+1];
}
if(SeqArr[pos+1]==null){
SeqArr[pos]=null;
}
}
else
System.out.print("No sequence to remove at specified position");
}
public void print(){
int i=0;
while (SeqArr[i]!=null){
System.out.println(i+"\t"+SeqArr[i].getType()+"\t"+SeqArr[i].getBioSeq().toString());
i++;
}
}
public void print(int pos){
if(SeqArr[pos]==null)
System.out.print("No sequence to print at specified position");
else
System.out.println(SeqArr[pos].getType()+"\t"+SeqArr[pos].getBioSeq().toString());
}
The custom data type i created that the array is made of
public class TypeSeq {
private Type type;
private MyLinkedList<Character> BioSeq;
public TypeSeq(Type type, MyLinkedList<Character> BioSeq){
this.type=type;
this.BioSeq=BioSeq;
}
public MyLinkedList<Character> getBioSeq() {
return BioSeq;
}
public void setBioSeq(MyLinkedList<Character> bioSeq) {
BioSeq = bioSeq;
}
public Type getType() {
return type;
}
public void setType(Type type) {
this.type = type;
}
}
and my DNAList class which handles input and contains the main method
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class DNAList {
static SequenceArr seqar;
public static void main(String []args){
MyLinkedList<String> hey=new MyLinkedList<>();
hey.append("Hello");
int arraysize= Integer.parseInt(args[0]);
String filePath=args[1];
File file=new File(filePath);
seqar=new SequenceArr(arraysize);
exefromFile(file);
}
public static void exefromFile(File file){
Scanner sc;
try{
sc=new Scanner(file);
while(sc.hasNextLine()){
String cmd=sc.nextLine();
if(!cmd.equals(""))
execute(cmd);
}
}catch (FileNotFoundException e){
e.printStackTrace();
}
}
public static void execute(String s){
s=s.trim();
String [] commands=s.split("\\s+");
switch (commands[0])
{
case "insert":
int pos=Integer.parseInt(commands[1]);
Type t=Type.fromString(commands[2]);
char [] charArr=commands[3].toCharArray();
MyLinkedList<Character> seq=new MyLinkedList<>(charArr.length);
char curChar;
for(int i=0;i<seq.length();i++){
curChar=charArr[i];
if(t==Type.DNA&&(curChar=='A'||curChar=='C'||curChar=='G'||curChar=='T'))
seq.append(charArr[i]);
else
System.out.print("Error occurred while inserting");
}
seqar.insert(pos,t,seq);
break;
case "remove":
pos=Integer.parseInt(commands[1]);
seqar.remove(pos);
break;
case "print":
if(commands.length>1&&commands[1]!=null){
pos=Integer.parseInt(commands[1]);
seqar.print(pos);
}
else
seqar.print();
break;
case "clip":
pos=Integer.parseInt(commands[1]);
int start =Integer.parseInt(commands[2]);
int end =Integer.parseInt(commands[3]);
seqar.clip(pos,start,end);
break;
case "copy":
int pos1=Integer.parseInt(commands[1]);
int pos2=Integer.parseInt(commands[2]);
seqar.copy(pos1,pos2);
break;
case "transcribe":
pos=Integer.parseInt(commands[1]);
seqar.transcribe(pos);
break;
}
}
}
The input .txt file will say something like
insert 0 DNA AATTCCGGAATTCCGG
print
but the output will just be
0 DNA
and the sequence will not be printed. Any ideas?
There are quite a lot of bugs in the code, to mention some:
MyLinkedList(int size){
this();
}
MyLinkedList(){
curr=tail=head=new Node<E>(null);
size=0;
}
this always initialises your list with size 0.
char [] charArr=commands[3].toCharArray();
MyLinkedList<Character> seq=new MyLinkedList<>
(charArr.length);
I don't get the point of initialising your list with the size of 4 every-time. Also note, it's not going to initialise with the given size as you are always overriding it with 0.
#Override
public void insert(E item) {
curr.setNext(new Node<E>(item, curr.Next()));
if(tail==curr)
tail=curr.Next();
size++;
}
You are not utilising the concept of head at all, your first insert is a special case and needs to handled wisely.
#Override
public String toString() {
String result = "";
Node current = head;
while(current.Next() != null){
result += current.data();
if(current.Next() != null){
result += ", ";
}
current = current.Next();
}
return "" + result;
}
head is always going to be null, when you print it's always going to result in first element being null. Moreover, when you find a node with it's next pointing to null, you should use its data. In your code, before returning the result you need to append the data from the last element too.

How can I compare two strings and return the lexicographical ordered result using the compareTo method?

I am trying to use compareTo method to compare two different names. After running the first attempt the program terminates immediately without returning anything. How can I modify this compareTo method to compare the names (Name n and Name n2) and return the result (-1, 1 or 0)? And obviously a print statement can be added to display (equal, before , or after) for the comparison. Thanks for any assistance.
//First attempt
public class Name implements Comparable<Name> {
private String Name;
public Name(String string) {
// TODO Auto-generated constructor stub
}
public String getName() {
return Name;
}
public int compareTo(Name other) {
if (getName().compareTo(other.getName()) < 0) {
return -1;
} else if (getName().compareTo(other.getName()) > 0) {
return 1;
} else if (getName().equals(other.getName())) {
return 0;
}
return getName().compareTo(other.getName());
}
public static void main(String[] args) {
Name n = new Name("jennifer");
n.getName();
Name n2 = new Name("paul");
n2.getName();
}
}
//second attempt
public class Name implements Comparable<String> {
private String Name;
public String getName() {
return Name;
}
public int compareTo(String other) {
if (getName().compareTo(other.getName()) < 0) {
return -1;
} else if (getName().compareTo(other.getName()) > 0) {
return 1;
} else if (getName().equals(other.getName())) {
return 0;
}
return getName().compareTo(other.getName());
}
public static void main(String[] args) {
String Name = new String("jennifer");
String other = new String("paul");
}
}
//First attempt
public class Name {
public static void main(String[] args) {
String n = new String("jennifer");
String n2 = new String("paul");
if (n.compareTo(n2) < 0) {
System.out.println(n +" is before than " +n2);
} else if (n.compareTo(n2) > 0) {
System.out.println(n +" is after than " +n2);
} else if (n.compareTo(n2) == 0) {
System.out.println(n +" is equals to " +n);
}
}
}
Outoput:
jennifer is before than paul
By the way, check this out because every programming language has its own set of rules and conventions and for variables in Java is like this:
If the name you choose consists of only one word, spell that word in
all lowercase letters. If it consists of more than one word,
capitalize the first letter of each subsequent word.
public class Name implements Comparable<Name> {
private String name;
public Name(String name) {
this.name=name;
}
public String getName() {
return name;
}
public int compareTo(Name other) {
if (getName().compareTo(other.getName()) < 0) {
return -1;
} else if (getName().compareTo(other.getName()) > 0) {
return 1;
} else if (getName().equals(other.getName())) {
return 0;
}
return getName().compareTo(other.getName());
}
public static void main(String[] args) {
Name n = new Name("jennifer");
n.getName();
Name n2 = new Name("paul");
n2.getName();
System.out.println(n.getName());
System.out.println(n2.getName());
System.out.println(n2.compareTo(n));
}
}
OUTPUT :
jennifer
paul
1

Confusion on using instanceof along with other inherited data

I have already made a posting about this program once, but I am once again stuck on a new concept that I am learning (Also as a side note; I am a CS student so please DO NOT simply hand me a solution, for my University has strict code copying rules, thank you.). There are a couple of difficulties I am having with this concept, the main one being that I am having a hard time implementing it to my purposes, despite the textbook examples making perfect sense. So just a quick explanation of what I'm doing:
I have an entity class that takes a Scanner from a driver. My other class then hands off the scanner to a superclass and its two subclasses then inherit that scanner. Each class has different data from the .txt the Scanner read through. Then those three classes send off their data to the entity to do final calculations. And that is where my problem lies, after all the data has been read. I have a method that displays a new output along with a few methods that add data from the super along with its derived classes.EDIT: I simply cannot figure out how to call the instance variable of my subclasses through the super so I can add and calculate the data.
Here are my four classes in the order; Driver, Entity, Super, Subs:
public static final String INPUT_FILE = "baseballTeam.txt";
public static void main(String[] args) {
BaseballTeam team = new BaseballTeam();
Scanner inFile = null;
try {
inFile = new Scanner(new File(INPUT_FILE));
team.loadTeam(inFile);
team.outputTeam();
} catch (FileNotFoundException e) {
System.out.println("File " + INPUT_FILE + " Not Found.");
System.exit(1);
}
}
}
public class BaseballTeam {
private String name;
private Player[] roster = new Player[25];
Player pitcher = new Pitcher();
Player batter = new Batter();
BaseballTeam() {
name = "";
}
public String getName() {
return name;
}
public void setName(String aName) {
name = aName;
}
public void loadTeam(Scanner input) {
name = input.nextLine();
for (int i = 0; i < roster.length; i++) {
if (i <= 9) {
roster[i] = new Pitcher();
}
else if ((i > 9) && (i <= 19)) {
roster[i] = new Batter();
}
else if (i > 19) {
roster[i] = new Player();
}
roster[i].loadData(input);
roster[i].generateDisplayString();
//System.out.println(roster[i].generateDisplayString()); //used sout to test for correct data
}
}
public void outputTeam() {
if ((pitcher instanceof Player) && (batter instanceof Player)) {
for (int i = 0; i < roster.length; i++) {
System.out.println(roster[i].generateDisplayString());
}
}
//How do I go about doing calculates?
public int calculateTeamWins() {
if ((pitcher instanceof ) && (batter instanceof Batter)) {
}
return 0;
}
public int calculateTeamSaves() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public double calculateTeamERA() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public double calculateTeamWHIP() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public double calculateTeamBattingAverage() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public int calculateTeamHomeRuns() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public int calculateTeamRBI() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
public int calculateStolenBases() {
if ((pitcher instanceof Pitcher) && (batter instanceof Batter)) {
}
return 0;
}
}
public class Player {
protected String name;
protected String position;
Player(){
name = "";
position = "";
}
public String getName() {
return name;
}
public void setName(String aName) {
name = aName;
}
public String getPosition() {
return position;
}
public void setPosition(String aPosition) {
position = aPosition;
}
public void loadData(Scanner input){
do {
name = input.nextLine();
} while (name.equals(""));
position = input.next();
//System.out.println(generateDisplayString());
}
public String generateDisplayString(){
return "Name: " + name + ", Position:" + position;
}
}
public class Pitcher extends Player {
private int wins;
private int saves;
private int inningsPitched;
private int earnedRuns;
private int hits;
private int walks;
private double ERA;
private double WHIP;
Pitcher() {
super();
wins = 0;
saves = 0;
inningsPitched = 0;
earnedRuns = 0;
hits = 0;
walks = 0;
}
public int getWins() {
return wins;
}
public void setWins(int aWins) {
wins = aWins;
}
public int getSaves() {
return saves;
}
public void setSaves(int aSaves) {
saves = aSaves;
}
public int getInningsPitched() {
return inningsPitched;
}
public void setInningsPitched(int aInningsPitched) {
inningsPitched = aInningsPitched;
}
public int getEarnedRuns() {
return earnedRuns;
}
public void setEarnedRuns(int aEarnedRuns) {
earnedRuns = aEarnedRuns;
}
public int getHits() {
return hits;
}
public void setHits(int aHits) {
hits = aHits;
}
public int getWalks() {
return walks;
}
public void setWalks(int aWalks) {
walks = aWalks;
}
#Override
public void loadData(Scanner input) {
super.loadData(input);
wins = input.nextInt();
saves = input.nextInt();
inningsPitched = input.nextInt();
earnedRuns = input.nextInt();
hits = input.nextInt();
walks = input.nextInt();
}
#Override
public String generateDisplayString() {
calculateERA();
calculateWHIP();
return String.format(super.generateDisplayString() + ", Wins:%1d, Saves:%1d,"
+ " ERA:%1.2f, WHIP:%1.3f ", wins, saves, ERA, WHIP);
}
public double calculateERA() {
try {
ERA = ((double)(earnedRuns * 9) / inningsPitched);
} catch (ArithmeticException e) {
ERA = 0;
}
return ERA;
}
public double calculateWHIP() {
try {
WHIP = ((double)(walks + hits) / inningsPitched);
} catch (ArithmeticException e) {
WHIP = 0;
}
return WHIP;
}
}
public class Batter extends Player {
private int atBats;
private int hits;
private int homeRuns;
private int rbi;
private int stolenBases;
private double batAvg;
Batter() {
super();
atBats = 0;
hits = 0;
homeRuns = 0;
rbi = 0;
stolenBases = 0;
}
public int getAtBats() {
return atBats;
}
public void setAtBats(int aAtBats) {
atBats = aAtBats;
}
public int getHits() {
return hits;
}
public void setHits(int aHits) {
hits = aHits;
}
public int getHomeRuns() {
return homeRuns;
}
public void setHomeRuns(int aHomeRuns) {
homeRuns = aHomeRuns;
}
public int getRbi() {
return rbi;
}
public void setRbi(int aRbi) {
rbi = aRbi;
}
public int getStolenBases() {
return stolenBases;
}
public void setStolenBases(int aStolenBases) {
stolenBases = aStolenBases;
}
#Override
public void loadData(Scanner input) {
super.loadData(input);
atBats = input.nextInt();
hits = input.nextInt();
homeRuns = input.nextInt();
rbi = input.nextInt();
stolenBases = input.nextInt();
}
#Override
public String generateDisplayString() {
calculateBattingAverage();
return String.format(super.generateDisplayString() +
", Batting Average:%1.3f, Home Runs:%1d, RBI:%1d, Stolen Bases:%1d"
, batAvg, homeRuns, rbi, stolenBases);
}
public double calculateBattingAverage() {
try{
batAvg = ((double)hits/atBats);
} catch (ArithmeticException e){
batAvg = 0;
}
return batAvg;
}
}
Also, its probably easy to tell I'm still fairly new here, because I just ran all my classes together in with the code sample and I can't figure out to add the gaps, so feel free to edit if need be.
The typical usage of instanceof in the type of scenario you're describing would be
if (foo instanceof FooSubclass) {
FooSubclass fooSub = (FooSubclass) foo;
//foo and fooSub now are references to the same object, and you can use fooSub to call methods on the subclass
} else if (foo instanceof OtherSubclass) {
OtherSubclass otherSub = (OtherSubclass) foo;
//you can now use otherSub to call subclass-specific methods on foo
}
This is called "casting" or "explicitly casting" foo to FooSubclass.
the concept to call the methods of your subclasses is called polymorphism.
In your runtime the most specific available method is called provided that the method names are the same.
so you can
Superclass class = new Subclass();
class.method();
and the method provided that overwrites the method in Superclass will be called, even if it's defined in the Subclass.
Sorry for my english, I hope that helps a little bit ;-)

Error at Linked list (java)

I created my own linked list, but when I tried to run it there is an error:
Exception in thread "main" java.lang.NullPointerException
at List.add(List.java:8) //if(t.val ==null)
at main.main(main.java:38) //linput.add(inputLine.split(" ")[i]);
Here is my List class:
class List{
String val;
List next=null;
private List t;
public void add(String word){
if(t.val ==null)
t.val=word;
else while(!t.next.val.equals(null))
{
t=t.next;
if(t.next.val.equals(null))
{
t.next.val=word;
break;
}
}
}
public int get(String word)
{
int i=0;
if(t.val.equals(word))
i=0;
else while(!t.next.val.equals(word))
{
t=t.next;
i++;
if(t.next.val.equals(word))
{
i++;
}
}
return i;
}
public String indexOf(int i)
{
int counter=0;
while(counter<i)
{
t=t.next;
counter++;
}
return t.val;
}
}
And here is my main function :
static public void main(String[] args)
{
List linput = new List();
String inputLine = "Hey look at me.";
for(int i = 0 ; i < inputLine.split(" ").length ; i++)
{
linput.add(inputLine.split(" ")[i]);
}
System.out.println(linput.indexOf(0)+" "+linput.indexOf(1)+" "+linput.indexOf(2));
}
I initialized t but next time there is an error like this:
private List t =new List();
Exception in thread "main" java.lang.StackOverflowError
at List.<init>(List.java:5)
at List.<init>(List.java:5)
at List.<init>(List.java:5)
Sorry. I can't give my full code, because the rest of my code is working well (reading from txt etc....).
The error seems to be related to the variable 't' (i.e., private List t).
Did you initialize this variable ? The if (t.val == null) seems to be cribbing this as t is null (uninitialized) at this point
You should have allocated object (using new) for this variable.
Can you share the full code for the constructor of List ?
Assuming you want to implement a simple forward list, rather than use the Java LinkedList class, you need to:
Change your implementation of the list to reference nodes in the list
handle traversal of the linked nodes in your word list
Here is an example:
WordList class
package com.example.words;
class WordList {
private WordNode head = null;
private int listSize = 0;
public void add(String word) {
// TODO add check for duplicate word
if (head == null) {
head = new WordNode();
head.setValue(word);
listSize++;
} else {
WordNode current = head;
while (current.getNext() != null) {
current = current.getNext();
}
WordNode newNode = new WordNode();
newNode.setValue(word);
current.setNext(newNode);
listSize++;
}
}
public int getWordIndex(String word) {
WordNode current = head;
int index = 0;
boolean found = false;
while (!found && current != null) {
found = current.getValue().equalsIgnoreCase(word);
if (!found) {
index++;
current = current.getNext();
}
}
if (found) {
return index;
} else {
return -1;
}
}
public String indexOf(int i) {
int index = 0;
WordNode current = head;
if (i <= listSize) {
while (index < i) {
current = current.getNext();
index++;
}
return current.getValue();
} else {
return null;
}
}
public int size() {
return listSize;
}
}
WordNode Class
package com.example.words;
public class WordNode {
private String value;
private WordNode next = null;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public WordNode getNext() {
return next;
}
public void setNext(WordNode link) {
next = link;
}
}
Test Driver
package com.example.words;
public class Test {
public static void main(String[] args) {
//TODO handle punctuation
WordList myList = new WordList();
String inputLine = "Hey look at me.";
String[] pieces = inputLine.split(" ");
for (int i=0; i < pieces.length; i++) {
myList.add(pieces[i]);
}
for (int i=0; i < pieces.length; i++) {
String value = myList.indexOf(i);
if (value.equalsIgnoreCase(pieces[i])) {
System.out.println("Following node is wrong:");
}
System.out.println ("node " + i + ". = " + value);
}
}
}
You tried to create t as a member variable of its own class like this:
class List {
[...]
private List t = new List();
[...]
}
This won't work because the constructor of List would be called indefinitely.
Try lazy instantiation of t instead. Replace all access of t with a getter:
private List getT() {
if (this.t == null) {
this.t = new List();
}
return t;
}

Categories

Resources