Currently I am working on a project in which I have to use this UML diagram to create and additional class I understand everything but I am baffled by the last line.
compareTo(wordToCompare : Word) : Integer
Since Word is the name of the class how would I insert an argument? I tried inputting an Object as an argument but it says:
Object is an incompatible type with Word.
I researched if Word was a non primitive data-type but could not find any information. I am rather inexperienced and quite confused if anyone could lend some assistance I would be greatly appreciative.
Word class UML
-wordCharacters : String
-count : integer
+ CONSTRUCTOR (word : String)
+ getWord() : String
+ getCount() : Integer
+ incrementCount() : void
+ toString() : String
+ equals(wordtoCompare : Object) : Boolean
+ compareTo(wordtoCompare : Word) : Integer
#Override
public boolean equals(Object wordtoCompare) {
boolean flag = false;
String currentWord = wordtoCompare.getClass().getName();
this.compareTo(wordtoCompare);
return flag;
}
public Integer compareTo(Word wordtoCompare) {
return 0;
}
you are overriding the equals method and it should look a bit like this.
You need to check if the Object wordtoCompare is of the type Word or if it´s the current object. After you did check if it´s a type or subtype of Word you can cast the wordtoCompare to an actuall Word object and do your stuff with it.
#Override
public boolean equals(Object wordtoCompare) {
boolean flag = false;
if(wordtoCompare == this) return true;
if(!(wordtoCompare instanceof Word)) return false;
Word word = (Word)wordtoCompare;
this.compareTo(word);
// Whatever you do with your flag
return flag;
}
Something like this I guess
class Word{
String wordCharacters;
int count;
public Word(String word){
...
}
.. other stuff
public int compareTo(Word other){
return wordCharacters.compareTo(other.wordCaracters)
}
}
You can just create the compareTo Method having a Word parameter. (Word is the class you're currently creating)
public class Word{
....
public int compareTo(Word wordToCompare){
int result = 0;
//do your compare stuff
return result;
}
}
If this isn't your problem, I may did not understand the problem properly
Edit:
Your equals Method looks the following:
public boolean equals(Object wordtoCompare) {
boolean flag = false;
String currentWord = wordtoCompare.getClass().getName();
this.compareTo(wordtoCompare);
return flag;
}
But you have to make sure, that the Object you're working with is really a Word.
#Override
public boolean equals(Object wordtoCompare) {
boolean flag = false;
if(wordtoCompare == this) return true;
if(!(wordtoCompare instanceof Word)) return false;
Word word = (Word)wordtoCompare;
int compareResult = this.compareTo(wordtoCompare);
// Whatever you do with your flag
return flag;
}
This method is taken from Kevin Esche, as he implemented this method properly. Thank you.
And then you have to implement compareTo properly.
Related
I have a project where I need to convert the value of x into 1+5 and calculate it to 6.
I have no problem if x is the only value that needs to be converted, but if I have (5*x) it becomes an issue. Rather than doing 5*(1+5) and calculate it to 30, it simply tries to compute 5*x and this results to an exception that says it cannot compute because a variable is present.
The ExpFoo class is an interface and it's the superclass of TimesExpFoo, PlusFoo, IntFoo and VarFoo. Replacement class is completely separated.
TimesExpFoo multiplies the number and PlusFoo adds the numbers.
Here's the Main class. This gets the varfoo and numbers. The Replacement class puts the varfoo and numbers in a hashmap that's used by the Replacement class. The varfoo is the key and the numbers are the values.
ExpFoo x = new VarFoo("x");
ExpFoo e1 = new IntFoo(1);
ExpFoo e2 = new IntFoo(2);
ExpFoo e5 = new IntFoo(5);
ExpFoo times = new TimesExpFoo(e5, x);
Replacement s = new Replacement();
s.put(new VarFoo("x"), new PlusExpFoo(e1, e5));
times.computeValue(s);
System.out.println(times.computeValue(s));
It will then go to ExpFoo class using computeValue method, the subst contains [x:=1+5], it will first check the applyReplacement method:
default int computeValue(Replacement subst) {
ExpFoo specialised = applyReplacement(subst);
return specialised.computeValue();
}
It will then go to TimesExpFoo class using applyReplacement method, it will return [x:=1+5]:
#Override
public ExpFoo applyReplacement(Replacement s) {
return this;
}
It will go to back ExpFoo class, this time specialised has (5*x) and subst has [x:=1+5], it will unfortunately return specialised value which is (5*x):
default int computeValue(Replacement subst) {
ExpFoo specialised = applyReplacement(subst);
return specialised.computeValue();
}
It will then go to TimesExpFoo's computeValue method, the getLeft method contains 5 and getRight method contains x:
#Override
public int computeValue() {
return getLeft().computeValue() * getRight().computeValue();
}
Which will finally go to the VarFoo class and use the computeValue method which will throw an error that it cannot compute because of a variable present.
I'm aware that TimesExpFoo's applyReplacement method returns the value of subst itself and I could do more with it but I'm not sure how it works. I've tried using return s.get((VarFoo) getRight()) but it will just give me a casting error TimesExpFoo cannot be cast to class VarFoo.
My VarFoo class overrides the equals and hashcodes methods. If the varfoo, x, has the same hashcode and it should overwrite 5*x with 5*(1+5). It has no problem doing it on its own.
I'm puzzled by the fact that it wouldn't overwrite the x variable. Does it has something to do with the hashmap?
My applyReplacement method is just a signature in the Expression class, so I doubt that's the issue.
Here's the Replacement class which uses hashmap:
public class Replacement {
private Map<VarFoo, ExpFoo> replacementMap;
public Replacement() {
replacementMap = new HashMap<>();
}
public ExpFoo put(VarFoo var, ExpFoo exp) {
if(replacementMap.containsKey(null) || replacementMap.containsValue(null)){
throw new NullPointerException();
}
return replacementMap.put(var, exp);
}
public boolean forget(VarFoo var) {
if(replacementMap.containsKey(null)) {
throw new NullPointerException();
}
else {
if(!replacementMap.containsKey(var))
return true;
}
return false;
}
public ExpFoo get(VarFoo var) {
if(replacementMap.containsKey(null)){
throw new NullPointerException();
}
return replacementMap.get(var);
}
public boolean hasMappingFor(VarFoo var) {
if(replacementMap.containsKey(var)){
return true;
}
else if(replacementMap.containsKey(null)){
throw new NullPointerException();
}
return false;
}
}
My VarFoo's equals and hashcode methods, it uses the instance variable name which is a String:
#Override
public boolean equals(Object o) {
if (o == null) return false;
if (!(o instanceof VarFoo))
return false;
if (o == this)
return true;
return name.equals(((VarFoo) o).name);
}
#Override
public int hashCode() {
int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
The TimesExpFoo class is a subclass of BinaryExpFoo which is an abstract class and it's the subclass of ExpFoo. The BinaryExpFoo is the one that gives the left, right and operatorSymbol instance variables.
public class TimesExpFoo extends BinaryExpFoo {
public TimesExpFoo(ExpFoo left, ExpFoo right) {
super(left, right, "*");
}
#Override
public int computeValue() {
return getLeft().computeValue() * getRight().computeValue();
}
#Override
public ExpFoo applyReplacement(Replacement s) {
return this;
}
#Override
public boolean equals(Object o) {
if (!(o instanceof TimesExpFoo)) {
return false;
}
return super.equals(o);
}
#Override
public int hashCode() {
return super.hashCode();
}
The HashMap uses hashCode and equals to check if the key already present in the map. If the key already exists the old value is replaced with a new one. The key itself remains unmodified.
If you want to use instances of the VarFoo class as HashMap keys, you have to override the hashCode() method so that it adheres to the contract: Equal objects return the same hashCode.
One common way is to let our IDE generate the equals() and hashCode() method for your VarFoo class
The goal of your applyReplacement() method is to replace all the variables by their real values/expressions. The only expression which can do that is obviously the VarFoo class. Its method might look like this:
#Override
public ExpFoo applyReplacement(Replacement s) {
ExpFoo exp = s.get(this);
exp = exp.applyReplacement(s); // replace any contained variables as well
return exp;
}
Similar to the computeValue() method, the applyReplacement() method has to be implemented recursively for classes which contain other ExpFoo objects. These "inner" expressions has to be "transformed" as well, where the variables are being replaced. As an example, for the TimesExpFoo class the method might look like this:
#Override
public ExpFoo applyReplacement(Replacement s) {
return new TimesExpFoo(
this.left.applyReplacement(s),
this.right.applyReplacement(s)
);
}
This way the TimesExpFoo object gets translated to a similar TimesExpFoo object without any variables anymore. Then you can use your computeValue() method since everything has been replaced.
Your actual implementation has to check for chained variable replacements. Imagine you have the expressions:
x = 5
y = 4+x
z = 3+y
You might need some kind of loops or recursive calls (like shown above) so the expression z will finally be transformed into 3+4+5 and not just stop at 3+y.
I am having a little trouble with my homework. I have to have a boolean isHigherGeneration() method that compares 2 CPU objects based on their generation. I was able to make my code compare the 2 objects, but I need the result to return YES/NO instead of true/false. I tried creating a string and transforming it into a boolean, but it didn't work. Can someone help me please? Here is my code:
public boolean isHigherGeneration(CPU cpu){
String YES = "YES";
String NO = "NO";
boolean t = Boolean.valueOf(YES);
boolean n = Boolean.valueOf(NO);
if (this.generation > cpu.generation)
return t ;
else
return n;
}
Thank you in advance for your help :)
It sounds from the question like it doesn't want you to return a boolean, but a String with either the value YES or the value NO instead of a boolean, so what you need to do is translate the result of the boolean expression into a String with the value YES or the value NO.
Thus, in this case, there's no need to play around with boolean in your code. You can compare the CPU generation and just return YES if the value is true and NO if the value is false:
public String isHigherGeneration(CPU cpu) {
if (generation > cpu.generation) {
return "YES";
} else {
return "NO";
}
}
Edit: From the sounds of the requirements, you need a boolean method that returns String, which is impossible. (That's like saying you want to buy an apple but end up with a pear.) If you do need a String result and a boolean method, you could divide them into three like this:
// Boolean method
public boolean isHigherGeneration(CPU cpu) {
return generation > cpu.generation;
}
// String method
public String toYesNo(boolean result) {
if (result) {
return "YES";
} else {
return "NO";
}
}
// Converter
public String isHigherGenerationYesNo(CPU cpu) {
return toYesNo(isHigherGeneration(cpu));
}
but this just all seems silly. I think maybe we're having a misunderstanding in the question. Could you post the question verbatim so that we can ensure that we've understood it correctly?
If you want to return "YES" or "NO", the return type of the method must be a String:
public String isHigherGeneration(CPU cpu) {
if (this.generation > cpu.generation)
return "YES";
else
return "NO";
}
or
public String isHigherGeneration(CPU cpu) {
return this.generation > cpu.generation ? "YES" : "NO";
}
I am currently learning about Java's hashcode via MOOC and followed their tutorial. However, expected output returns null when there clearly is a value inside hashmap. My code for override is following:
public class Plate{
private final String regCode;
private final String country;
// Counstructors
...
// accessors... only showing name for less clutter
getCode()
getCountry()
#Override // toString
public String toString(){
return country + " " + regCode;
}
#Override // equals
public boolean equals(Object obj){
if(obj == null){
return false;
}
if(getClass() != obj.getClass()){
return false;
}
Plate cmp = (Plate) obj;
if(this.country.equals(cmp.getCountry())){
return false;
}
if(this.regCode == null || this.regCode.equals(cmp.getCode())){
return false;
}
return true;
}
///////////////////////////////////// Below code may be the problem ///////////////////////////////////
#Override // hashCode
public int hashCode(){
if(this.country == null || this.regCode == null){
return 7;
}
return this.country.hashCode() + this.regCode.hashCode();
}
}
and my main function that uses above code is:
import java.util.ArrayList;
import java.util.HashMap;
public class Regi{
public static void main(String[] args){
Plate reg1 = new Plate("FI", "ABC-123");
Plate reg2 = new Plate("FI", "UXE-465");
Plate reg3 = new Plate("D", "B WQ-431");
ArrayList<Plate> finnish = new ArrayList<Plate>();
finnish.add(reg1);
finnish.add(reg2);
Plate newPlate = new Plate("FI", "ABC-123");
if(!finnish.contains(newPlate)){
finnish.add(newPlate);
}
System.out.println("Finnish " + finnish);
// where unexpected result occur
HashMap<Plate, String> owners = new HashMap<Plate, String>();
owners.put(reg1, "Arto");
owners.put(reg3, "Jurgen");
System.out.println("Owners:");
System.out.println(owners.get(reg1));
System.out.println(owners.get(new Plate("FI", "ABC-123")));
System.out.println(owners.get(new Plate("D", "B WQ-431")));
}
}
Where expected output is:
but my output displays null below "owners:" portion whenever I ran System.out.println(owners.get(new Plate("FI", "ABC-123"))); and System.out.println(owners.get(new Plate("D", "B WQ-431")));. I'm not sure what is wrong with my custom hashCode function since I was able to print out both of my hashCode for country and regCode and they both gave numeric values. I also referenced someone else's post regarding to hashcode to use prime number but it was still displaying null. I was wondering if anyone can point me to right direction regarding to hashCode.
Your code doesn't work, because you make equals return false when the two object have the same country. Or the same regCode:
if(this.country.equals(cmp.getCountry())){
return false;
}
if(this.regCode == null || this.regCode.equals(cmp.getCode())){
return false;
}
You're missing the ! (NOT) operator:
if (! this.country.equals(cmp.getCountry())) {
return false;
}
if (this.regCode == null || ! this.regCode.equals(cmp.getCode())) {
return false;
}
Also, your hashCode() implementation implies that country can be null, so you're missing the null-check:
if (this.country == null || ! this.country.equals(cmp.getCountry())) {
return false;
}
I need to use indexOf to find numbers inside a string, and it gives me the error:
Type mismatch: cannot convert from int to boolean.
public static boolean validPassword(String password) {
if(password.length() >= 8 ){
return true;
}
else if (password.indexOf("0")) {
return true;
}
return false;
}
Don't use index. You can use String.matches().
String str = "ksksks8ksksksksksks";
System.out.println(str.matches(".*\\d.*"));
Honestly though, if you can do it anyway you want, I would simply write a method as follows. Regular expressions are great for complicated patterns but they are also expensive in terms of processing.
public static boolean containsNumber(String str) {
boolean found = false;
for (char c : str.toCharArray()) {
if (Character.isDigit(c)) {
found = true;
break;
}
}
return found;
}
You could also modify the above and call it indexOf and iterate thru the characters using a regular for loop. Then returning either the location of the first digit or -1 just like the String version of indexOf().
And finally, for fun, you could use the Streams capability of Java 8+.
public static boolean containsNumber(String str) {
return str.chars().filter(Character::isDigit).count() > 0;
}
below is my code that checks the incoming model and modifies the source accordingly, checking if its ALLCAPS or Firstcap. The problem I am having is when the model contains a symbol e.g. matchCase("I'm","apple"). This would return apple, when it's supposed to return Apple. On the other hand, If I use "Im", it modifies it correctly to "Apple". Is there a way i can modify it that would work. I tried to run a few methods but I keep getting stuck
public static String matchCase(String model, String source){
boolean o = true;
if(model.toUpperCase().equals(model)){
source = source.toUpperCase();
}
if(Character.isUpperCase(model.charAt(0))){
for(int i=1;i<model.length();i++){
if(Character.isLowerCase(model.charAt(i)) == false){
o = false;
}
}
// if(o == model.length()-1){
if(o == true){
String can = "";
for(int j=0;j<source.length();j++){
if(j==0){
can += Character.toUpperCase(source.charAt(j)); }
else{
can += source.charAt(j);
}
}
source = can;
// Character.toUpperCase(source.charAt(0));
}
}
return source;
}
}
I think your problem comes from the fact that
Character.isLowerCase('\'') // is false
You should change this test
if(Character.isLowerCase(model.charAt(i)) == false)
By
if(Character.isUpperCase(model.charAt(i)))
If you know your model is always going to be either uppercase or firstcap can't you do something like this:
public static String matchCase(String model, String source){
if(model.toUpperCase() == model)
return source.toUpperCase();
// capitalize the first letter of source and send back
return Character.toUpperCase(source.charAt(0)) + source.substring(1);
}