Comparing 2 objects, wrong equals() and hashcode? - java

can somebody tell me why it returns "not equal"? Im searching for this for a long time and nothing... I think there is problem with my hashcode or/and equals method.
public class Main {
public static void main(String[] args) {
Student s1 = new Student();
s1.setFirstName("Kamil");
s1.setLastName("Witam");
s1.setMark(3.0);
s1.setAge(12);
Student s2 = new Student();
s2.setFirstName("Kamil");
s2.setLastName("Witam");
s2.setMark(3.0);
s2.setAge(12);
if( s1.equals(s2)){
System.out.println("równe");
}
else{
System.out.println("sraka");
}
}
}
And my hashCode:
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ( ( firstName == null ) ? 0 : firstName.hashCode() );
result = prime * result + ( ( lastName == null ) ? 0 : lastName.hashCode() );
long temp;
temp = Double.doubleToLongBits( mark );
result = prime * result + (int) ( temp ^ ( temp >>> 32 ) );
return result;
}
And equals:
public boolean equals( Object obj )
{
if ( this == obj )
return true;
if ( obj == null )
return false;
if ( getClass() != obj.getClass() )
return false;
Student other = (Student) obj;
if ( age != other.age )
return false;
if ( firstName == null )
{
if ( other.firstName != null )
return false;
}
else
if ( !firstName.equals( other.firstName ) )
return false;
if ( lastName == null )
{
if ( other.lastName != null )
return false;
}
else
if ( !lastName.equals( other.lastName ) )
return false;
if ( mark != other.mark )
return false;
return true;
}
Can somebody explain it to me :/? Thanks

Related

Simplifying conditional logic for readibility

I have following code that sets vrstaProizvoda.
private String napraviVrstuProizvoda(String kreditJeAktivanKod, String idArmPlana) {
String vrstaProizvoda = null;
if (kreditJeAktivanKod != null && kreditJeAktivanKod.equals("Y")) {
vrstaProizvoda = VrstaProizvoda.STEP.value();
} else if (idArmPlana != null && !idArmPlana.isEmpty() && !idArmPlana.equals("0000")){
vrstaProizvoda = VrstaProizvoda.ARM.value();
}
return vrstaProizvoda;
}
Looking at else if statement, everything is negating values. Is there a better way to write idArmPlana condition so it is easier to read? Or is it not worth it?
You could write something along the lines of:
!(idArmPlana == null || idArmPlana.isEmpty() || idArmPlana.equals("0000"))
The logic is still the same, but it is slightly more readable. Having long chains of and's or or's is never super readable, but doing something like this where you have your simple conditions, or them together, then negate the result can work.
To make it easier to read, just create small functions that have a logical name:
private String napraviVrstuProizvoda(String kreditJeAktivanKod, String idArmPlana) {
String vrstaProizvoda = null;
if (isYes(kreditJeAktivanKod)) {
vrstaProizvoda = VrstaProizvoda.STEP.value();
} else if (!isZero(idArmPlana)){
vrstaProizvoda = VrstaProizvoda.ARM.value();
}
return vrstaProizvoda;
}
function boolean isYes(String string){
return (null != string && string.equals("Y");
}
function boolean isZero(String string){
return (null != string && !string.isEmpty() && string.equals("0000");
}
Not entirely sure about Arrays.asList, but the recurring idArmPlana could be used just once:
return "Y".equals(kreditJeAktivanKod)
? VrstaProizvoda.STEP.value()
: !Arrays.<String>asList("", "0000", null).contains(idArmPlana)
? VrstaProizvoda.ARM.value()
: null;
Using Apache commons-lang3 library you can:
import org.apache.commns.lang3.StringUtils;
if (StringUtils.isNotBlank(StringUtils.stripStart(idArmPlana,"0")))
stripStart stolen from How to remove leading zeros from alphanumeric text?
My preference is one of these:
private String napraviVrstuProizvoda(String kreditJeAktivanKod, String idArmPlana) {
if ( (kreditJeAktivanKod != null) && kreditJeAktivanKod.equals("Y") ) {
return VrstaProizvoda.STEP.value();
} else if ( (idArmPlana != null) && !idArmPlana.isEmpty() && !idArmPlana.equals("0000") ) {
return VrstaProizvoda.ARM.value();
} else {
return null;
}
}
private String napraviVrstuProizvoda(String kreditJeAktivanKod, String idArmPlana) {
if ( strEquals(kreditJeAktivanKod, "Y") ) {
return VrstaProizvoda.STEP.value();
} else if ( !strIsEmpty(idArmPlana) && !strEquals(idArmPlana, "0000") ) {
return VrstaProizvoda.ARM.value();
} else {
return null;
}
}
Here are a number of rewrites to show a range of alternatives, and to show how to reach the above with incremental adjustments:
Rewritten with more spaces and parenthesis. This makes it easier to pick out the long variable names, and relieves the reader of all need to organize the expression logic:
private String napraviVrstuProizvoda(String kreditJeAktivanKod, String idArmPlana) {
String vrstaProizvoda = null;
if ( (kreditJeAktivanKod != null) && kreditJeAktivanKod.equals("Y") ) {
vrstaProizvoda = VrstaProizvoda.STEP.value();
} else if ( (idArmPlana != null) && !idArmPlana.isEmpty() && !idArmPlana.equals("0000") ) {
vrstaProizvoda = VrstaProizvoda.ARM.value();
}
return vrstaProizvoda;
}
Rewritten to remove the default 'null' value. Having such a value is problematic. Consider if the logic were much more complex. Having a default value takes away the opportunity for the compiler to detect unhandled cases.
private String napraviVrstuProizvoda(String kreditJeAktivanKod, String idArmPlana) {
String vrstaProizvoda;
if ( (kreditJeAktivanKod != null) && kreditJeAktivanKod.equals("Y") ) {
vrstaProizvoda = VrstaProizvoda.STEP.value();
} else if ( (idArmPlana != null) && !idArmPlana.isEmpty() && !idArmPlana.equals("0000") ) {
vrstaProizvoda = VrstaProizvoda.ARM.value();
} else {
vrstaProizvoda = null;
}
return vrstaProizvoda;
}
Rewritten with multiple return values. This is my preference, but some prefer a single return statement, as was present in the original method.
private String napraviVrstuProizvoda(String kreditJeAktivanKod, String idArmPlana) {
if ( (kreditJeAktivanKod != null) && kreditJeAktivanKod.equals("Y") ) {
return VrstaProizvoda.STEP.value();
} else if ( (idArmPlana != null) && !idArmPlana.isEmpty() && !idArmPlana.equals("0000") ) {
return VrstaProizvoda.ARM.value();
} else {
return null;
}
}
Rewritten, with helper methods (see below). This is a little clearer, but at a cost of obscuring the test logic. Splitting code into a lot of small methods, while often encouraged, is not always preferred in practice.
private String napraviVrstuProizvoda(String kreditJeAktivanKod, String idArmPlana) {
if ( strEquals(kreditJeAktivanKod, "Y") ) {
return VrstaProizvoda.STEP.value();
} else if ( !strIsEmpty(idArmPlana) && !strEquals(idArmPlana, "0000") ) {
return VrstaProizvoda.STEP.value();
} else {
return null;
}
}
Helper methods:
// Test that two strings are equal. Handle null values.
private boolean strEquals(String value1, String value2) {
if ( value1 == null ) {
return ( value2 == null );
} else if ( value2 == null ) {
return false;
} else {
return value1.equals(value2);
}
}
// Test that two strings are equal. Handle null values.
private boolean strEquals(String value1, String value2) {
boolean result;
if ( value1 == null ) {
result = ( value2 == null );
} else if ( value2 == null ) {
result = false;
} else {
result = value1.equals(value2);
}
return result;
}
// Test if a string is neither null nor empty.
private boolean strIsNotEmpty(String value) {
return ( (value != null) && !value.isEmpty() );
}
To add one more alternative to the already given good answers:
private String napraviVrstuProizvoda(String kreditJeAktivanKod, String idArmPlana) {
return Optional.ofNullable(kreditJeAktivanKod).filter(e->e.equals("Y"))
.isPresent()? VrstaProizvoda.STEP.value() :
Optional.ofNullable(idArmPlana).filter(e->!e.equals("0000")).filter(e->!e.isEmpty())
.isPresent()? VrstaProizvoda.ARM.value():
null;
}

Making a password verification into a class

I have a program grabbing a password from the user, then it checks if the conditions are met or not then outputs "Valid Password" or "Invalid Password". This works, and I was able to turn the verification aspect into a method in the same program and it works, but I want to make it into a class where I can just say if( validate(pw) == true ) ... or at least if( v.getValidation() == true ) ... in any program and it will test my conditions. I've used custom classes before but for some reason everything I try does not work on this one, I've been at it for days.
Here's my method:
public boolean validate( String pw )
{
boolean l = false, u = false, lo = false, d = false, r = true;
if( pw.length() >= 6 )
{ l = true; }
for( int i = 0; i < pw.length(); i++ )
{
if( Character.isUpperCase( pw.charAt(i) ) )
{ u = true; }
if( Character.isLowerCase( pw.charAt(i) ) )
{ lo = true; }
if( Character.isDigit( pw.charAt(i) ) )
{ d = true; }
}
if( l == false || u == false || lo == false || d == false )
{ r = false; }
return r;
}
Edit:
Thank you all for your input, this is what it came out to in the end:
public class Password
{
public static boolean validate( String pw )
{
boolean result = false;
int upper = 0, lower = 0, digit = 0;
if( pw.length() >= 6 )
{
for( int i = 0; i < pw.length(); i++ )
{
if( Character.isUpperCase( pw.charAt(i) ) )
{ upper++; }
if( Character.isLowerCase( pw.charAt(i) ) )
{ lower++; }
if( Character.isDigit( pw.charAt(i) ) )
{ digit++; }
}
}
if( upper >= 1 && lower >= 1 && digit >= 1 )
{ result = true; }
return result;
}
}
You do not need to make a whole class for this. You can do something like:
public static void main(String[] args) {
boolean valid = validate("PassWord22");
}
public static boolean validate( String pw ) {}
Also some notes on your method:
You don't need to do l == true or l == false in your if statement. You can simply do:
if( !l || !u || !lo || !d )
{ r = false; }
In fact you can just return
return l && u && lo && d;
If the length is not 6 or greater, simply return false. This will save checking all the letters in the String
I would come up with better variable names. Single/two letter variable names makes it very hard to tell what they represent, and easy to mix up. (instead of l you could have length and instead of u you could have upper)
Also this can be easier solved with regex and String.matches():
public static boolean validate(String pw) {
String pattern = "^(?=.*\\d)(?=.*[a-z])(?=.*[A-Z]).+$";
return (pw.length() > 5 && pw.matches(pattern));
}
I got it working, turned out to be an error in the code that the compiler was not picking up. I wanted to delete the question but they wont let me for some reason. So in case you're curious this is what my class looks like functioning:
public class Password
{
private String pw;
public Password()
{
pw = "";
}
public Password( String pw )
{
this.pw = pw;
}
public boolean getPassword( String pw )
{
boolean l = false, u = false, lo = false, d = false, r = true;
if( pw.length() >= 6 )
{ l = true; }
for( int i = 0; i < pw.length(); i++ )
{
if( Character.isUpperCase( pw.charAt(i) ) )
{ u = true; }
if( Character.isLowerCase( pw.charAt(i) ) )
{ lo = true; }
if( Character.isDigit( pw.charAt(i) ) )
{ d = true; }
}
if( l == false || u == false || lo == false || d == false )
{ r = false; }
return r;
}

How to run this portion of code?

i found this snippet of code on stack and i wanted to try it out on my machine but it keeps giving me an error of
Main method not found in class Main, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
can anyone help me figure out what to do?
This is the portion of the code i wanted to try on my machine
public static void main(String[] args) {
}
public int parse(String input) {
Scanner scanner = new Scanner(input);
return consumeLine(scanner);
}
public int consumeLine(Scanner scanner) {
if( scanner.hasNext("(") ) {
return consumeExpression(scanner);
} else if( scanner.hasNext("IF") ) {
return consumeIf(scanner);
}
return 0;
}
public int consumeExpression(Scanner scanner) {
scanner.next("(");
int a = scanner.nextInt();
int b = scanner.nextInt();
String op = scanner.next("[+-/*]");
scanner.next(")");
if( "+".equals(op) ) {
return a + b;
} else if( "-".equals(op) ) {
return a - b;
}
throw new RuntimeException("parsing error");
}
public int consumeIf(Scanner scanner) {
scanner.next("IF");
int exp1 = consumeExpression(scanner);
int exp2 = consumeExpression(scanner);
int exp3 = consumeExpression(scanner);
int exp4 = consumeExpression(scanner);
if( exp1 < 0 ) {
return exp2;
} else if( exp1 == 0 ) {
return exp3;
}
throw new RuntimeException("should not be here (TM)");
}
Try this.
public int parse(String input) {
Scanner scanner = new Scanner(input);
return consumeLine(scanner);
}
public int consumeLine(Scanner scanner) {
if( scanner.hasNext("\\(") ) {
return consumeExpression(scanner);
} else if( scanner.hasNext("IF") ) {
return consumeIf(scanner);
}
return 0;
}
public int consumeExpression(Scanner scanner) {
scanner.next("\\(");
int a = scanner.nextInt();
int b = scanner.nextInt();
String op = scanner.next("[+-/*]");
scanner.next("\\)");
if( "+".equals(op) ) {
return a + b;
} else if( "-".equals(op) ) {
return a - b;
}
throw new RuntimeException("parsing error");
}
public int consumeIf(Scanner scanner) {
scanner.next("IF");
int exp1 = consumeExpression(scanner);
int exp2 = consumeExpression(scanner);
int exp3 = consumeExpression(scanner);
int exp4 = consumeExpression(scanner);
if( exp1 < 0 ) {
return exp2;
} else if( exp1 == 0 ) {
return exp3;
}
throw new RuntimeException("should not be here (TM)");
}
sample output
System.out.println(parse(" IF ( 0 0 - ) ( 1 1 + ) ( 2 2 + ) ( 3 3 + )"));
// -> 4

Implement REMOVE method for AVL Tree

I have imlemented so far http://pastebin.com/gXJVXdLS
5. Create a remove method. search the tree if the item is found, then you kill it. you have to then balance the tree in AVL fashion to properly fill the hole that you make. Again, use the wikipedia description (which is pretty good) along with the simulator or even maybe my lecture to get the remove working properly. I won't provide sample data on this one-- you can figure that out yourself at this point. just remember that aside from the general case you have two special cases requiring double rotations (see lecture or play with the simulator for cases where you have a left/right or right/left situation.)
Now I need to implement this function
public void remove(K input)
help me in that. I have done this
public void remove(K input) {
root = remove(root,input);
}
public AVLNode<K> remove(K x, AVLNode<K> t) {
if (t==null) {
System.out.println("Sorry but you're mistaken, " + t + " doesn't exist in this tree :)/>\n");
return null;
}
System.out.println("Remove starts... " + t.data + " and " + x);
if (x.compareTo(t.data) < 0 ) {
t.left = remove(x,t.left);
int l = t.left != null ? getHeight(t.left) : 0;
if((t.right != null) && (getHeight(t.right) - l >= 2)) {
int rightHeight = t.right.right != null ? getHeight(t.right.right) : 0;
int leftHeight = t.right.left != null ? getHeight(t.right.left) : 0;
if(rightHeight >= leftHeight)
t = rotateLeft(t);
else
t = rotateRight(t);//double
}
}
else if (x.compareTo(t.data) > 0) {
t.right = remove(x,t.right);
int r = t.right != null ? getHeight(t.right) : 0;
if((t.left != null) && getHeight(t.left) - r >= 2) {
int leftHeight = t.left.left != null ? getHeight(t.left.left) : 0;
int rightHeight = t.left.right != null ? getHeight(t.left.right) : 0;
if(leftHeight >= rightHeight)
t = rotateRight(t);
else
t = rotateLeft(t);//and double
}
}
return t;
} //End of remove...
nvm found the answer
private AVLNode<K> findMin( AVLNode<K> t )
{
if( t == null )
return t;
while( t.left != null )
t = t.left;
return t;
}
public void remove( K x )
{
root = remove( x, root );
}
private AVLNode<K> remove( K x, AVLNode<K> t )
{
if( t == null )
return t; // Item not found; do nothing
int compareResult = x.compareTo( t.data );
if( compareResult < 0 )
t.left = remove( x, t.left );
else if( compareResult > 0 )
t.right = remove( x, t.right );
else if( t.left != null && t.right != null ) // Two children
{
t.data = findMin( t.right ).data;
t.right = remove( t.data, t.right );
}
else
t = ( t.left != null ) ? t.left : t.right;
return t;
}

boolean expression parser in java

Are there any java libraries or techniques to parsing boolean expressions piecemeal?
What I mean is given an expression like this:
T && ( F || ( F && T ) )
It could be broken down into a expression tree to show which token caused the 'F' value, like so (maybe something like this):
T && <- rhs false
( F || <- rhs false
( F && T ) <- eval, false
)
I am trying to communicate boolean expression evaluations to non-programmers. I have poked around with Anlr, but I couldn't get it to do much (it seems to have a bit of a learning curve).
I'm not opposed to writing it myself, but I'd rather not reinvent the wheel.
You could do this with MVEL or JUEL. Both are expression language libraries, examples below are using MVEL.
Example:
System.out.println(MVEL.eval("true && ( false || ( false && true ) )"));
Prints:
false
If you literally want to use 'T' and 'F' you can do this:
Map<String, Object> context = new java.util.HashMap<String, Object>();
context.put("T", true);
context.put("F", false);
System.out.println(MVEL.eval("T && ( F || ( F && T ) )", context));
Prints:
false
I've coded this using Javaluator.
It's not exactly the output you are looking for, but I think it could be a start point.
package test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import net.astesana.javaluator.*;
public class TreeBooleanEvaluator extends AbstractEvaluator<String> {
/** The logical AND operator.*/
final static Operator AND = new Operator("&&", 2, Operator.Associativity.LEFT, 2);
/** The logical OR operator.*/
final static Operator OR = new Operator("||", 2, Operator.Associativity.LEFT, 1);
private static final Parameters PARAMETERS;
static {
// Create the evaluator's parameters
PARAMETERS = new Parameters();
// Add the supported operators
PARAMETERS.add(AND);
PARAMETERS.add(OR);
// Add the parentheses
PARAMETERS.addExpressionBracket(BracketPair.PARENTHESES);
}
public TreeBooleanEvaluator() {
super(PARAMETERS);
}
#Override
protected String toValue(String literal, Object evaluationContext) {
return literal;
}
private boolean getValue(String literal) {
if ("T".equals(literal) || literal.endsWith("=true")) return true;
else if ("F".equals(literal) || literal.endsWith("=false")) return false;
throw new IllegalArgumentException("Unknown literal : "+literal);
}
#Override
protected String evaluate(Operator operator, Iterator<String> operands,
Object evaluationContext) {
List<String> tree = (List<String>) evaluationContext;
String o1 = operands.next();
String o2 = operands.next();
Boolean result;
if (operator == OR) {
result = getValue(o1) || getValue(o2);
} else if (operator == AND) {
result = getValue(o1) && getValue(o2);
} else {
throw new IllegalArgumentException();
}
String eval = "("+o1+" "+operator.getSymbol()+" "+o2+")="+result;
tree.add(eval);
return eval;
}
public static void main(String[] args) {
TreeBooleanEvaluator evaluator = new TreeBooleanEvaluator();
doIt(evaluator, "T && ( F || ( F && T ) )");
doIt(evaluator, "(T && T) || ( F && T )");
}
private static void doIt(TreeBooleanEvaluator evaluator, String expression) {
List<String> sequence = new ArrayList<String>();
evaluator.evaluate(expression, sequence);
System.out.println ("Evaluation sequence for :"+expression);
for (String string : sequence) {
System.out.println (string);
}
System.out.println ();
}
}
Here is the ouput:
Evaluation sequence for :T && ( F || ( F && T ) )
(F && T)=false
(F || (F && T)=false)=false
(T && (F || (F && T)=false)=false)=false
Evaluation sequence for :(T && T) || ( F && T )
(T && T)=true
(F && T)=false
((T && T)=true || (F && T)=false)=true
I recently put together a library in Java specifically to manipulate boolean expressions: jbool_expressions.
It includes a tool too parse expressions out of string input:
Expression<String> expr = ExprParser.parse("( ( (! C) | C) & A & B)")
You can also do some fairly simple simplification:
Expression<String> simplified = RuleSet.simplify(expr);
System.out.println(expr);
gives
(A & B)
If you wanted to step through the assignment then, you could assign values one by one. For the example here,
Expression<String> halfAssigned = RuleSet.assign(simplified, Collections.singletonMap("A", true));
System.out.println(halfAssigned);
shows
B
and you could resolve it by assigning B.
Expression<String> resolved = RuleSet.assign(halfAssigned, Collections.singletonMap("B", true));
System.out.println(resolved);
shows
true
Not 100% what you were asking for, but hope it helps.
Check out BeanShell. It has expression parsing that accepts Java-like syntax.
EDIT: Unless you're trying to actually parse T && F literally, though you could do this in BeanShell using the literals true and false.
Try this.
static boolean parseBooleanExpression(String s) {
return new Object() {
int length = s.length(), index = 0;
boolean match(String expect) {
while (index < length && Character.isWhitespace(s.charAt(index)))
++index;
if (index >= length)
return false;
if (s.startsWith(expect, index)) {
index += expect.length();
return true;
}
return false;
}
boolean element() {
if (match("T"))
return true;
else if (match("F"))
return false;
else if (match("(")) {
boolean result = expression();
if (!match(")"))
throw new RuntimeException("')' expected");
return result;
} else
throw new RuntimeException("unknown token");
}
boolean term() {
if (match("!"))
return !element();
else
return element();
}
boolean factor() {
boolean result = term();
while (match("&&"))
result &= term();
return result;
}
boolean expression() {
boolean result = factor();
while (match("||"))
result |= factor();
return result;
}
boolean parse() {
boolean result = expression();
if (index < length)
throw new RuntimeException(
"extra string '" + s.substring(index) + "'");
return result;
}
}.parse();
}
And
public static void main(String[] args) {
String s = "T && ( F || ( F && T ) )";
boolean result = parseBooleanExpression(s);
System.out.println(result);
}
output:
false
The syntax is
expression = factor { "||" factor }
factor = term { "&&" term }
term = [ "!" ] element
element = "T" | "F" | "(" expression ")"
mXparser handles Boolean operators - please find few examples
Example 1:
import org.mariuszgromada.math.mxparser.*;
...
...
Expression e = new Expression("1 && (0 || (0 && 1))");
System.out.println(e.getExpressionString() + " = " + e.calculate());
Result 1:
1 && (0 || (0 && 1)) = 0.0
Example 2:
import org.mariuszgromada.math.mxparser.*;
...
...
Constant T = new Constant("T = 1");
Constant F = new Constant("F = 0");
Expression e = new Expression("T && (F || (F && T))", T, F);
System.out.println(e.getExpressionString() + " = " + e.calculate());
Result 2:
T && (F || (F && T)) = 0.0
For more details please follow mXparser tutorial.
Best regards

Categories

Resources