How check number on symmetrics?
public static int Symmetric(int a) {
if(new StringBuilder(Integer.toString(a)) ==
new StringBuilder(Integer.toString(a)).reverse())
return a;
else
return 0;
}
I try do it smth like this but always return 0.
You can't use == to compare Strings (or StringBuilders), you need to use equals().
Also, you need to turn the StringBuilders back to Strings before comparing:
EDIT:
Also, there is really no need for the first StringBuilder:
public static int symmetric(int a) {
if (Integer.toString(a).equals(new StringBuilder(Integer.toString(a)).reverse().toString()))
return a;
else
return 0;
}
Equality is explained here in JLS.
You must use equals() on Strings: StringBuilder.toString().equals().
public static int Symmetric( int a ) {
return
new StringBuilder(Integer.toString(a)).toString().equals(
StringBuilder(Integer.toString(a)).reverse().toString())
? a : 0;
}
Related
I'm reading a file and adding the words to a HashSet and a TreeSet. HashSet.size() gives me 350 items but TreeSet.size() 349 items. Does anyone have an explanation of this difference?
public static void main(String[] args) throws FileNotFoundException {
File file = new File("src/words.txt");
Scanner read = new Scanner(file);
Set<Word> hashSet = new HashSet<Word>();
Set<Word> treeSet = new TreeSet<Word>();
while(read.hasNext()) {
Word word = new Word(read.next());
hashSet.add(word);
treeSet.add(word);
}
System.out.println(hashSet.size());
System.out.println(treeSet.size());
Iterator<Word> itr = treeSet.iterator();
while (itr.hasNext()) {
System.out.println(itr.next().toString());
}
}
public class Word implements Comparable<Word> {
private String word;
public Word(String str) {
this.word = str; }
public String toString() {
return word.toLowerCase(); }
/* Override Object methods */
public int hashCode() {
int hashCode = 0;
int temp;
for(int i = 0; i<word.length();i++){
temp = (int) word.charAt(i);
hashCode += temp^hashCode;
}
return hashCode;
}
public boolean equals(Word other) {
if(other instanceof Word){
if(compareTo(((Word) other))==0)
return true;
else
return false;}
else
return false;
}
public int compareTo(Word w) {
if(this.word.compareToIgnoreCase(w.toString())>0)
return 1;
if(this.word.compareToIgnoreCase(w.toString())<0)
return -1;
else
return 0;
}
}
Change your equals from equals(Word) to equals(Object). Please also add #Override attribute.
Moreover, your hashCode method does not guarantee that for two words that are equal (ignoring case), they will have the same hash code. You can use toUpperCase() on word before computing the hash code.
Your equals and compareTo method behaves differently for same input.
E.g.
Word w1 = new Word("Word");
Word w2 = new Word("word");
System.out.println(w1 == w2);
System.out.println(w1.equals(w2));
System.out.println(w1.compareTo(w2));
will give
false
true
0
HashSet uses equals method to compare keys, while TreeSet will use compareTo method to check equivalence of keys. Since your implementation is not correct, for different scenarios, hashset will treat keys as different while treeset might be considering them as same.
To know which values are getting treated as same by TreeSet you can print the result of addition to the Sets. Both will return true, if key does not exist otherwise false is returned.
while(read.hasNext()) {
Word word = new Word(read.next());
System.out.println(hashSet.add(word));
System.out.println(treeSet.add(word));
}
Here's my java code and the problem is that the use of relational
operator(<) inside binarySearch() is giving error.
I guess this error I am getting because the operands are of type object.
How to remove this error so my function runs perfectly?
import java.util.Random;
import java.util.Arrays;
class BinarySearch
{
public static void main(String $[])
{
Integer arr[]=new Integer[20];
for(int i=0;i<20;i++)
arr[i]=(new Random()).nextInt()%10000;
display("Initial array :\n");
array(arr);
Arrays.sort(arr);
display("After sorting :\n");
array(arr);
display("Enter the element to be searched for : ");
Integer elem=(new java.util.Scanner(System.in)).nextInt();
display(elem+(binarySearch(arr,elem)?" Found":" Not found")+"\n");
}
public static <T>boolean binarySearch(T arr[],T val)
{
int start=0;
int end=arr.length-1;
while(start<=end)
{
int mid=(start+end)/2;
if(arr[mid]==val)
return true;
if(arr[mid]<val)
start=mid+1;
else
end=mid-1;
}
return false;
}
public static void display(Object o)
{
System.out.print(o);
}
public static <T>void array(T arr[])
{
for(int i=0;i<arr.length;i++)
display(arr[i]+" ");
display("\n");
}
}
The problem is that your binarySearch() method is accepting parameters that will be Objects rather than primitive types, so it is unwise to compare them using the equality operator == and invalid to compare them using the less than operator <. Instead define your binarySearch method as follows:
public static <T extends Comparable<T>> boolean binarySearch(T arr[],T val) {
int start = 0;
int end = arr.length-1;
while(start <= end) {
int mid=(start+end)/2;
int comparison = arr[mid].compareTo(val);
if(comparison == 0) {
return true;
}
if(comparison < 0) {
start = mid+1;
}
else {
end = mid-1;
}
}
return false;
}
Read here about generics. Since all generics are objects - you can't use comparison operators with them. Even if you type <T extends Number.
There are two ways to handle this:
Pass Comparator<T> to the method and use comparator.compare(arr[mid], val) for comparing values.
Write <T extends Comparable> and call arr[mid].compareTo(val).
Both these methods return an integer value:
0, if values are equal
negative, if first value less than second
positive, if first value greater than second
I find it kind of confusing, I'm trying to solve this problem I found on the Internet as my programming exercise:
Implement a class with methods which takes one INTEGER parameter "initialValue" and returns following:
a. if initialValue is equal to 1 - return 2 (INTEGER)
b. if initialValue is equal to 2 - return 1 (INTEGER)
This is what I've done so far:
public static void main(String[] args) {
System.out.print(myMethod(1));
}
private static int myMethod(int initialValue) {
int n = 1;
if(initialValue == n) {
return 2;
} else {
return n;
}
}
But I guess this is a basic solution. Do you know any method variations other than this? Thanks.
little fancy solution would be doing XOR with 3
return initialValue ^ 3;
You might use the conditional operator ?: and something like
private static int myMethod(int initialValue) {
return initialValue == 1 ? 2 : 1;
}
The ternary operator is described in the Java Tutorials like
Another conditional operator is ?:, which can be thought of as shorthand for an if-then-else statement (discussed in the Control Flow Statements section of this lesson). This operator is also known as the ternary operator because it uses three operands. In the following example, this operator should be read as: "If someCondition is true, assign the value of value1 to result. Otherwise, assign the value of value2 to result."
I really hope that you plan on using this for learning only not to hand in as your own work. Your way works very well. However, you could also use the modulo operator (assuming of course that the only two inputs would be 1 and 2).
private static int myMethod(int initialValue) {
return initialValue % 2 + 1;
}
Best of luck with your CS aspirations!
public static void main(String[] args) {
int input;
// code for input value
System.out.print(myMethod(input));
}
private static int myMethod(int initialValue) {
int n = 1;
if(initialValue == n) {
return 2;
} else if(initialValue==2) {
return 1;
}
else {
return initialValue;
}
}
This might give better output if you insert values dynamically
It can also be done this way,
private static int myMethod(int initialValue) {
switch (initialValue){
case 1:
return 2;
case 2:
return 1;
default:
return 0;
}
}
Let's say I have a class called Number, and I intend to do a lot of equality comparisons of Number objects. I am concerned about the "overhead" (class comparison, etc...) of the generic Number::equals(Object o) method. In this case, is it useful to provide a method such as Number::isEqualTo(Number other) as an alternative to Number::equals(Object o)? Is this a common pattern? Or do JVMs currently optimize well enough that there is no advantage to doing this?
Here's a code example:
public class Number {
int _value;
Number(int value) {
_value = value;
}
#Override
public boolean equals(final Object o) {
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) return false;
return isEqualTo((Number)o);
}
public boolean isEqualTo(final Number other) {
return _value == other._value;
}
public static void main(String[] args) {
Number one = new Number(1);
Number two = new Number(2);
if (!one.isEqualTo(two)) {
System.out.println("fast comparison?");
}
if (!one.equals(two)) {
System.out.println("slow comparison?");
}
}
}
The two methods have different semantic:
equals has the semantic dictated by the Object::equals contract, while
isEqualTo has the semantic that applies exclusively to Number objects
Since the comparison is not apples-to-apples, it is fair that equals would require more CPU cycles. It is unlikely that you would notice the difference, however.
It is far more common for classes like yours to implement Comparable<T>. The semantic there calls for an ordering check, not just for an equality checks, but there is no requirement to take objects of unknown classes, letting you save CPU cycles.
You should have a good reason to provide an alternative to equality (e.g. a profiler run that points to equals(Object) as a bottleneck, a perceived improvement on readability due to the change, or achieving richer semantic due to adopting an interface that does more). Doing it for the sake of cutting a few CPU cycles would premature optimization.
A quick microbenchmark with the most unfavourable scenario (equals always calls isEqualTo) shows (in ms):
equals: 1014
isEqualTo: 1010
Bottom line: unless your program doesn't do anything else, this is not going to be a performance bottleneck and you should stick to the first principle of optimisation: profile first, then optimise what needs to be optimised.
Test code:
public class TestPerf {
private static int NUM_RUN;
private static List<Number> list = new ArrayList<>();
public static void main(String[] args) {
NUM_RUN = 100_000;
for (int i = 0; i < 10000; i++) {
list.add(new Number(i));
}
long sum = 0;
System.out.println("Warmup");
for (int i = 0; i < NUM_RUN; i++) {
sum += method1(17);
sum += method2(17);
}
System.gc();
System.out.println("Starting");
sum = 0;
long start = System.nanoTime();
for (int i = 0; i < NUM_RUN; i++) {
sum += method1(17);
}
long end = System.nanoTime();
System.out.println("equals: " + (end - start) / 1000000);
System.gc();
start = System.nanoTime();
for (int i = 0; i < NUM_RUN; i++) {
sum += method2(17);
}
end = System.nanoTime();
System.out.println("isEqualTo: " + (end - start) / 1000000);
System.out.println(sum);
}
private static int method1(int target) {
int sum = 0;
Number comparison = new Number(target);
for (Number n : list) {
if (n.equals(comparison)) sum++;
}
return sum;
}
private static int method2(int target) {
int sum = 0;
Number comparison = new Number(target);
for (Number n : list) {
if (n.isEqualTo(comparison)) sum++;
}
return sum;
}
public static class Number {
int _value;
Number(int value) {
_value = value;
}
#Override
public boolean equals(final Object o) {
if (o == this) return true;
if (o == null) return false;
if (o.getClass() != getClass()) return false;
return isEqualTo((Number) o);
}
public boolean isEqualTo(final Number other) {
return _value == other._value;
}
}
}
You may even provide an overload of equals itself: equals(Number). If you implement it very carefully (to be behaviorally indistinguishable from equals(Object)), you can achieve a minuscule speedup by avoiding a checked downcast in certain cases. Note that you are still going to have to check a.getClass() == b.getClass() so the difference is vanishingly small.
This depends on where you'd like to use a compare method.
Maybe you can use different implementations of a Comparator interface?
These can be used to eg. sort Lists.
xx.isEqualTo.yy is an comparison on "object" level. It simply checks whether this two object are referring the same object.
It is always better to write 'equations methods' for specific classes. For example in this case optimal comparison is simply ==.
What I do not understand is why I am getting an error compiling my code when a String is in fact an object, and the compiler is saying otherwise. I dont know why I keep getting this error message
symbol: method compareTo(Object)
location: variable least of type Object
.\DataSet.java:17: error: cannot find symbol
else if(maximum.compareTo(x) < 0)
here is the code. I'm trying to utilize the class comparable to allow two objects to use the compareTo method. In the tester, I'm just trying to use a basic string object to compare.
public class DataSetTester
{
public static void main(String[] args)
{
DataSet ds = new DataSet();
String man = "dog";
String woman = "cat";
ds.add(man);
ds.add(woman);
System.out.println("Maximum Word: " + ds.getMaximum());
}
}
Class:
public class DataSet implements Comparable
{
private Object maximum;
private Object least;
private int count;
private int answer;
public void add(Object x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public int compareTo(Object anObject)
{
return this.compareTo(anObject);
}
public Object getMaximum()
{
return maximum;
}
public Object getLeast()
{
return least;
}
}
Comparable Interface:
public interface Comparable
{
public int compareTo(Object anObject);
}
Of course String is an Object.
Comparable is generic now. Why do you feel the need to make those references Object if they are type String? Your code is poor; it's not a Java problem.
I don't see why DataSet needs to implement Comparable. You just need to compare incoming Strings as they're added. Do it this way and you'll fare better:
public class DataSet {
private String maximum;
private String least;
private int count;
private int answer;
public void add(String x) {
if(count == 0){
least = x;
maximum = x;
} else if (least.compareTo(x) > 0) {
least = x;
} else if(maximum.compareTo(x) < 0) {
maximum = x;
}
count++;
}
public String getMaximum() { return this.maximum; }
public String getLeast() { return this.least; }
public int getCount() { return this.count; }
}
The problem is that DataSet implements Comparable, but Object doesn't.
Instead of storing Objects, you want to store Comparables. However, if you do get this to compile, you will get into an infinite loop right here:
public int compareTo(Object anObject)
{
// Yeah, never stop loopin'!
return this.compareTo(anObject);
}
It's recommended that in newer code, you use the generic Comparable<T> interface. Your code would then look like this:
public class DataSet implements Comparable<DataSet>
{
private String maximum;
private String least;
private int count;
private int answer;
public void add(String x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public int compareTo(DataSet anObject)
{
// I don't really know how you want this to work.
// Come up with your own criteria on what makes a DataSet greater or less than
// another one.
count - anObject.count
}
// Good practice to include this if you're doing a compareTo.
#Override
public boolean equals(Object other)
{
return (other instanceof DataSet) && compareTo((DataSet)other) == 0;
}
public String getMaximum()
{
return maximum;
}
public String getLeast()
{
return least;
}
}
Edit - just saw that you're comparing strings. In that case, you don't really need DataSet to implement Comparable. However, if you do need it for something else, what I wrote still stands.
least and maximum are simply Objects, and the Object class doesn't have a compareTo(...) method, simple as that. least and maximum need to be declared Comparable, not Object. And as written, it makes no sense declaring DataSet to implement the Comparable interface since there are no DataSet objects present and certainly none being compared.
java.lang.Object does not have a compareTo() method.
First of all there is an infinite loop in you code:
public int compareTo(Object anObject)
{
return this.compareTo(anObject);
}
this method is continuously calling itself.
Regarding your compile error: you have declared variable as Object, which obviously does not have a compareTo method.
There is no compareTo() method in Object. I guess you're looking for String.compareTo().
Type checking is done at compile time and not runtime. At compile time, least and maximum are considered to be objects of type Object and not String.