private List<String> values = new ArrayList<String>();
public WhitespaceEqualsTest() {
values.add("I ");
values.add("I");
values.add(". ");
values.add(".");
values.add("1");
values.add("1 ");
System.out.println(refine(values));
}
private List<String> refine(List<String> input){
ArrayList<String> outerLoopValues = (ArrayList<String>) input;
ArrayList<String> innerLoopValues = (ArrayList<String>) input;
ArrayList<String> results = new ArrayList<String>();
for(String string1 : outerLoopValues){
for(String string2 : innerLoopValues){
if(string1.contains(string2) == false){
results.add(string1);
}
}
}
Set<String> temp = new HashSet<String>();
temp.addAll(results);
results.clear();
results.addAll(temp);
return results;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((values == null) ? 0 : values.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
WhitespaceEqualsTest other = (WhitespaceEqualsTest) obj;
if (values == null) {
if (other.values != null)
return false;
} else if (!values.equals(other.values))
return false;
return true;
}
I've overriden the hashCode() and equals(), so I'm not really sure what's wrong. They are generated using Eclipse (Source -> Generate hashCode() and equals()). Why isn't it detecting that the same character without a space is contained within a character with a space? The output is:
[1, . , I , I, ., 1 ]
As mentioned in one of the comments, you should be using a String wrapper to wrap the strings and override the equals and hashcode methods.
My solution is based on the assumption that "I " should be equals to "I", hence only one of them should be added into the result.
However I'll need to addon that based on the documentation in Java Objects
and Java Arraylist with regards to equals and contains implementation respectively. The hashcode method would have to return a common value. I've written the explanation in the code as comments. Let me know if there are any issues.
Main Class
public class StackOverflowMain
{
private static List<String> values = new ArrayList<String>();
public static void main(String[] args) {
values.add("I ");
values.add("I");
values.add(". ");
values.add(".");
values.add("1");
values.add("1 ");
List<WhitespaceEqualsTest> toRefineList = new ArrayList<WhitespaceEqualsTest>();
for (String value : values) {
toRefineList.add(new WhitespaceEqualsTest(value));
}
System.out.println(refine(toRefineList));
}
private static List<WhitespaceEqualsTest> refine(List<WhitespaceEqualsTest> input) {
ArrayList<WhitespaceEqualsTest> loopValues = (ArrayList<WhitespaceEqualsTest>) input;
ArrayList<WhitespaceEqualsTest> results = new ArrayList<WhitespaceEqualsTest>();
for (WhitespaceEqualsTest value : loopValues) {
if (!results.contains(loopValues)) {
results.add(value);
}
}
Set<WhitespaceEqualsTest> temp = new HashSet<WhitespaceEqualsTest>();
temp.addAll(results);
results.clear();
results.addAll(temp);
return results;
}
}
Inner WhitespaceEqualsTest Class
class WhitespaceEqualsTest {
private String value;
public WhitespaceEqualsTest(String value) {
this.value = value;
}
public void setString(String value) {
this.value = value;
}
public String getString() {
return this.value;
}
public int hashCode() {
/*
* Arraylist.contains is evaluated by using (o==null ? e==null : o.equals(e)) as mentioned in the javadoc
* and Object.equals() would evaluate using hashcode() first to check if the object o is equal to object e
* before calling .equals() method to evaluate.
*
* As mentioned in java doc at http://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#equals(java.lang.Object)
* c1.equals(c2) implies that c1.hashCode()==c2.hashCode() should be satisfied
* which is not in this question
*/
return 0;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
WhitespaceEqualsTest other = (WhitespaceEqualsTest) obj;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.contains(other.value) && !other.value.contains(value)){
/*
* Does a checking on both ends since "I " contains "I" but "I" does not contain "I " due to the whitespace
* For this question, if one of the condition satisfy it should be equal
*/
return false;
}
return true;
}
#Override
public String toString() {
return this.value;
}
}
Result
[I , . , 1]
String class is final. So you cannot override its equals and hashCode methods.
private List<StringWrapper> values = new ArrayList<StringWrapper>();
public WhitespaceEqualsTest() {
values.add(new StringWrapper("I "));
values.add(new StringWrapper("I"));
values.add(new StringWrapper(". "));
values.add(new StringWrapper("."));
values.add(new StringWrapper("1"));
values.add(new StringWrapper("1 "));
System.out.println(refine(values));
}
private List<StringWrapper> refine(List<StringWrapper> input){
//no need to iterate the list
//the set will automatically cancel out the duplicate
Set<StringWrapper> temp = new HashSet<StringWrapper>(input);
ArrayList<StringWrapper> results = new ArrayList<StringWrapper>();
results.addAll(temp);
return results;
}
Create a wrapper class of String then override the equals and hashcode method.
class StringWrapper {
private String value;
public StringWrapper(String value){
this.value = value;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
#Override
public String toString(){
return value;
}
#Override
public boolean equals(Object obj){
boolean result = Boolean.FALSE;
if(obj != null && obj instanceof StringWrapper){
StringWrapper stringWrapper = (StringWrapper) obj;
result = value.trim().equals(stringWrapper.getValue().trim());
}
return result;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((value.trim() == null) ? 0 : value.trim().hashCode());
return result;
}
}
You add the values to a Set. In a Set in any case a value occurs once - hence it is a set. ;)
You might as well modify the loop to see what happens
for(String string1 : outerLoopValues){
for(String string2 : innerLoopValues){
if(string1.contains(string2) == false){
results.add(string1);
System.out.println("added \"" + string1 + "\" since it does not contain \"" + string2 + "\"");
}
}
}
Giving the following output:
added "I " since it does not contain ". "
added "I " since it does not contain "."
added "I " since it does not contain "1"
added "I " since it does not contain "1 "
added "I" since it does not contain "I "
added "I" since it does not contain ". "
added "I" since it does not contain "."
added "I" since it does not contain "1"
added "I" since it does not contain "1 "
......
[1, . , I , I, ., 1 ]
To add them if they do not contain each other is the idea i guess?
Then pushing the List through a Set removes the duplicates! See here: Does adding a duplicate value to a HashSet/HashMap replace the previous value
Changing the condition in the Loop from false to true yields this (no change after using the Set/HashSet in the last line of output!)
added "I " since it does contain "I "
added "I " since it does contain "I"
added "I" since it does contain "I"
added ". " since it does contain ". "
added ". " since it does contain "."
added "." since it does contain "."
added "1" since it does contain "1"
added "1 " since it does contain "1"
added "1 " since it does contain "1 "
[1, . , I , I, ., 1 ]
Which answers your question: It does detect if e.g. "I " contains "I".
System.out.println("I ".contains("I"));
says "true"
Hope this helps ^^-d
Related
I need to create a method that return the index of an object in a list by comparing one of its fields.
I have 2 classs A and B with overrided Equals() and HashCode() methods like this:
Class A:
public class A {
private String field1;
private String field2;
//getters and setters
#Override
public boolean equals (Object o){
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
A that = (A) o;
return field1.equals(that.field1);
}
#Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + field1.hashCode();
return result;
}
}
Class B :
public class B {
private String field1;
private String field2;
//getters and setters
#Override
public boolean equals (Object o){
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
B that = (B) o;
return field2.equals(that.field2);
}
#Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + field2.hashCode();
return result;
}
}
In my main program I need to implement a generic method that returns the index of an item within an ArrayList<> of A or B.
private int getObjectIndexFromList(List<A or B> list, A or B param){
int index;
try{
index = list.indexOf(list.stream().filter(e -> e.equals(param)));
}catch (NoSuchElementException ex){
index = -1;
}
return index;
}
So my question is how to pass generic params for the method ?
I'm assuming you want to compare with either A.field1, A.field2, B.field1, or B.field1?
In that case you can use a lambda to find it in the stream. Like this:
private <T> int getObjectIndexFromList(List<T> list, Predicate<T> predicate){
int index;
try {
index = list.indexOf(list.stream()
.filter(predicate)
.findFirst()
.get());
} catch (NoSuchElementException ex){
index = -1;
}
return index;
}
Then you just use it like this:
int index = getObjectIndexFromList(listOfAs, a -> a.field1.equals("foo"));
Using streams here isn't optimal though since you're effectively traversing the list twice and checking equality on both the parametar and the sought object. Using a list iterator that keeps track of the current index is be more efficient:
private <T> int getObjectIndexFromList(List<T> list, Predicate<T> predicate){
ListIterator<T> it = list.listIterator();
while (it.hasNext()) {
// Get the item and it's index in the list
int index = it.nextIndex();
T item = it.next();
if (predicate.test(item)) {
// We found it, return the index
return index;
}
}
// We didn't find anything
return -1;
}
Here's an example of it in use:
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("foobar");
list.add("fubar");
list.add("Hello World!");
System.out.printf("String with length %s has index %s%n",
5, getObjectIndexFromList(list, s -> s.length() == 5));
}
And the output:
String with length 5 has index 3
If you have override hashcode and equals methods... why don't you make a plain call to 'List.indexOf'?
Make them extend the same abstract class (I don't know the exact problem, but if they have end in the same List is highly probable that they will end being family) and use it.
IndexOf uses 'equals' to find the index of the object so it must work...
I am working on this question. It seems like that I have found the right answer and returns true but then it is overwritten by false.. Newbie in Java, sorry if it is a dummy question.. How do I just return true?
Thank you in advance
Question
Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words.
For example, given
s = "leetcode",
dict = ["leet", "code"].
Return true because "leetcode" can be segmented as "leet code".
import java.util.HashSet;
import java.util.Set;
public class Hi {
public static void main(String[] args) {
String str = "leetcode";
Set<String> set = new HashSet<String>();
set.add("leet");
set.add("code");
boolean b = wordBreak(str, set);
System.out.println("b is " + b);
}
public static boolean wordBreak(String s, Set<String> wordDict) {
if(s.length() == 0 || wordDict.isEmpty()) {
return false;
}
return helper(s, wordDict, 0);
}
public static boolean helper(String s, Set<String> wordDict, int index) {
if(index == s.length()) {
System.out.println("1 is called.. ");
return true;
}
int curIndex = index;
System.out.println("curIndex is " + curIndex);
while(index < s.length()) {
//System.out.println("s.length() is " + s.length());
curIndex++;
if(curIndex > s.length()) {
System.out.println("2 is called.. ");
//return false;
return false;
}
if(wordDict.contains(s.substring(index, curIndex))) {
System.out.println(s.substring(index, curIndex) + " curIndex is " + curIndex);
helper(s, wordDict, curIndex);
}
}
System.out.println("3 is called.. ");
return false;
}
output:
curIndex is 0
leet curIndex is 4
curIndex is 4
code curIndex is 8
1 is called..
2 is called..
2 is called..
b is false
This might not answer your question but I just mentioned an approach, and by no means I'm saying that my approach is better or more optimal.
In your code, there is no return true statement. The code does the right work but at the very end, since loop doesn't break anywhere, it always returns false. I mean you need to return true somewhere based on some condition and one of such conditions I mentioned in my below example.
private static boolean test(String str, Set<String> set) {
int i = 1;
int start = 0;
List<String> tokens = new ArrayList<String>();
while (i <= str.length()) {
String substring = str.substring(start, i);
if (set.contains(substring)) {
tokens.add(substring);
start = substring.length();
}
i++;
}
String abc = "";
for (String a : tokens) {
abc = abc + a;
}
System.out.println(abc);
if (abc.equals(str)) {
return true;
} else {
return false;
}
}
Below is the screenshot from debug trace from within debugger.
I need some help with designing the logic of my problem.
Model Bean
package com.ashish.model;
public class Model {
public Integer a,b,c,d;
public String f,g,h,i,j;
}
Service Class
package com.ashish.service;
import com.ashish.model.Model;
public class Service {
public StringBuilder query = null;
public Service(){
query = new StringBuilder("Select * from A where ");
}
public String build(Model m){
if(m.a != null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
query.append("a="+m.a);
if(m.a == null&&m.b!=null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
query.append("b="+m.b);
if(m.a == null&&m.b==null&&m.c!=null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
query.append("c="+m.c);
if(m.a == null&&m.b==null&&m.c==null&&m.d!=null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
query.append("d="+m.d);
if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e!=null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
query.append("e="+m.e);
if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f!=null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
query.append("f="+m.f);
if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g!=null&&m.h==null&&m.i==null&&m.j==null)
query.append("g="+m.g);
if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h!=null&&m.i==null&&m.j==null)
query.append("h="+m.h);
if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i!=null&&m.j==null)
query.append("i="+m.i);
if(m.a == null&&m.b==null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j!=null)
query.append("j="+m.j);
if(m.a != null&&m.b!=null&&m.c==null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
query.append("a="+m.a);query.append(" b="+m.b);
if(m.a != null&&m.b==null&&m.c!=null&&m.d==null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
query.append("a="+m.a);query.append(" c="+m.c);
if(m.a != null&&m.b==null&&m.c==null&&m.d!=null&m.e==null&&m.f==null&&m.g==null&&m.h==null&&m.i==null&&m.j==null)
query.append("a="+m.a);query.append(" d="+m.d);
// ... 512 lines in this pattern
return query.toString();
return query.toString();
}
}
I want to write public String build(Model m) in such a way so that I would not have to write 512 if-else condition.
Conditions:
All instance variables of Model class can have two value ( null, not null)
They all can be null or they all can be not null.
There would be total 512 combinations ( since every instance variable have two state and there are 9 instance variable so total number of condition would be 2^9 )
Order of the instance variable does not matter.
My project use Java 6 so I can not use switch on String.
I have looked into various pattern but none of them is meeting my requirement.
Thanks for looking
A private helper method as follows should do it -
private void appendIfNotNull(String fieldOp, String val) {
if(val != null) {
query.append(fieldOp).append(val);
}
}
Then just call it in the build method -
public String build(Model m) {
appendIfNotNull("a=", m.a); //no null check, just need to repeat this for all fields
Maybe you want to try to use Java Reflection to read all fields of your Model and read them. You don't need to know the field name to read it. So it would be fully dynamic and generic, even if you extend your Model class.
Class modelClass = Class.forName(Model.class.getName());
Field[] fields = circleClass.getFields(); //includes all fields declared in you model class
for (Field f : fields) {
System.out.println("field " + f.getName() + " has value: " + f.get(<YOUR_MODEL_INSTANCE>));
}
Example code adapted from:
- http://forgetfulprogrammer.wordpress.com/2011/06/13/java-reflection-class-getfields-and-class-getdeclaredfields/
Will this code make sense?
interface ToStringer {
void appendTo(StringBuilder sb);
}
class NullToStringer implements ToStringer {
public void appendTo(StringBuilder sb) {
// Do nothing
}
}
class IntegerToStringer implements ToStringer {
private String fieldName;
private Integer val;
public IntegerToStringer(String fieldName, Integer val) {
this.fieldName = fieldName;
this.val = val;
}
public void appendTo(StringBuilder sb) {
sb.append(field).append(" = ").append(val);
}
}
public class ToStringFactory {
public ToStringer getToStringer(String fieldName, Integer val) {
if (val == null) {
return new NullToStringer();
} else {
return new IntegerToStringer(fieldName, val);
}
}
public ToStringer getToStringer(String fieldName, String val) {
...
}
}
public String build(Model m){
ArrayList<ToStringInstance> list = ...;
list.add(ToStringFactory.getToStringer("f", m.f));
list.add(ToStringFactory.getToStringer("g", m.g));
list.add(ToStringFactory.getToStringer("h", m.h));
StringBuilder sb = ...;
for (ToStringInstance tsi : list) {
tsi.appendTo(sb);
}
return sb.toString();
}
I am not sure what logic you are trying to implement, but the general approach: creating interface, concrete implementaion of printing values, using NullValue pattern to hide null problem and using factory to control objects creation should do the trick.
By using this approach you can avoid problems with 2^9 combinations by avoiding multiple if-else statements.
Update. Just came to my mind. You can use reflection. Iterate through all fields, get value of each, print it if it is no null. Maybe this will be enough.
It seems like you want to append to the query for each element that is not null. This can be done quite simply with an auxiliary method or two:
public class Service {
public StringBuilder query = null;
public Service(){
query = new StringBuilder("Select * from A where ");
}
public String build(Model m) {
boolean added = first;
first &= !maybeAdd("a", m.a, first);
first &= !maybeAdd("b", m.b, first);
. . . // all the rest of the fields of m
}
/**
* Add an equality test to an SQL query if the value is not {#code null}.
* #param key the field name for the query
* #param value the value to test for equality
* #param first flag indicating that no conditions have been added
* #return {#code true} if the value was appended; {#code false} otherwise.
*/
private boolean maybeAdd(String key, Object value, boolean first) {
if (value != null) {
if (!first) {
query.append(" AND ");
}
query.append(key).append('=').append(value);
return true;
}
return false;
}
}
Note that if all fields of the model are null, your query will not be correctly formed. You might want to include the appropriate logic in the maybeAdd method to compensate for that.
As I mentioned in my comment, you don't need a different if for every combination. You just need to append the values that are not null, and ignore the ones that are. Let me know if this works for you.
public String build(Model m) {
// use this to know when to add " AND " to separate existing values
boolean appended = false;
if (m.a != null) {
query.append("a=" + m.a);
appended = true;
}
if (m.b != null) {
if (appended) {
query.append(" AND ");
}
query.append("b=" + m.b);
appended = true;
}
if (m.c != null) {
if (appended) {
query.append(" AND ");
}
query.append("c=" + m.c);
appended = true;
}
if (m.d != null) {
if (appended) {
query.append(" AND ");
}
query.append("d=" + m.d);
appended = true;
}
if (m.e != null) {
if (appended) {
query.append(" AND ");
}
query.append("e=" + m.e);
appended = true;
}
if (m.f != null) {
if (appended) {
query.append(" AND ");
}
query.append("f=" + m.f);
appended = true;
}
if (m.g != null) {
if (appended) {
query.append(" AND ");
}
query.append("g=" + m.g);
appended = true;
}
if (m.h != null) {
if (appended) {
query.append(" AND ");
}
query.append("h=" + m.h);
appended = true;
}
if (m.i != null) {
if (appended) {
query.append(" AND ");
}
query.append("i=" + m.i);
appended = true;
}
if (m.j != null) {
if (appended) {
query.append(" AND ");
}
query.append("j=" + m.j);
appended = true;
}
return query.toString();
}
I don't know why you need two if statements for this:
if( m.a == null) {
query.append("m=null");
} else {
query.append("m="+m.a);
}
if( m.b == null) {
query.append("m=null");
} else {
query.append("m="+m.b);
}
I have defined a simple private class named SetOb which contains an int and a Set data structure. I have a HashMap in the 'main' method with SetOb as Key and Integer as value. Now as you can see in the main method, when I feed the HashMap with a SetOb instance and then look for an instance with exactly the same value, it returns 'null'. This has happened with me quite a few times before when I use my own defined data structures like SetOb as Key in HashMap. Can someone please point me what am I missing ?
Please note that in the constructor of SetOb class, I copy the Set passed as argument.
public class Solution {
public static Solution sample = new Solution();
private class SetOb {
public int last;
public Set<Integer> st;
public SetOb(int l , Set<Integer> si ){
last = l;
st = new HashSet<Integer>(si);
}
}
public static void main(String[] args) {
Map<SetOb, Integer> m = new HashMap< SetOb, Integer>();
Set<Integer> a = new HashSet<Integer>();
for(int i =0; i<10; i++){
a.add(i);
}
SetOb x = sample.new SetOb(100, a);
SetOb y = sample.new SetOb(100, a);
m.put(x,500);
Integer val = m.get(y);
if(val!= null) System.out.println("Success: " + val);
else System.out.println("Failure");
}
}
Your x and y are not the same object instances hence contains is not able to match y against x, which ends up not finding the matching key/value in the Map.
If you want the match to succeed, please implement(override) hasCode & equals method in SetOb which will compare the field values.
Sample methods(Eclipse generated) as below:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + last;
result = prime * result + ((st == null) ? 0 : st.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
SetOb other = (SetOb) obj;
if (last != other.last)
return false;
if (st == null) {
if (other.st != null)
return false;
} else if (!st.equals(other.st))
return false;
return true;
}
The default implementation of hashCode uses object identity to determine the hash code. You will need to implement hashCode (and equals) in your private class if you want value identity. For instance:
private class SetOb {
public int last;
public Set<Integer> st;
public SetOb(int l , Set<Integer> si ){
last = l;
st = new HashSet<Integer>(si);
}
#Override
public boolean equals(Object other) {
if (other.class == SetOb.class) {
SetOb otherSetOb = (SetOb) other;
return otherSetOb.last == last && otherSetOb.st.equals(st);
}
return false;
}
#Override
public int hashCode() {
return 37 * last + st.hashCode();
}
}
SetOb needs to override the hashCode() and thus the equals() methods.
Hash-based collections use these methods to store (hashCode()) and retrieve (hashCode()) and equals()) your objects.
I have developed a pojo named Employee.java. Now I was planning to make it as user defined collection. I want to make a map and store all the employee type objects in it.
Below is my pojo
public class Employee {
String name,job;
int salary;
public Employee(String n , String j, int t ) //constructor
{
this.name= n;
this.job=j;
this.salary= t;
}
#Override
public int hashCode()
{
return name.hashCode()+job.hashCode()+salary;
}
#Override
public boolean equals(Object obj) {
Employee e = (Employee) obj;
return this.name.equals(e.name)&&this.job.equals(e.job)&&this.salary==e.salary;
}
}
Now I have developed another class that contains map and will store employee type objects..
public static void main(String[] args)
{
Map employeeMap = new HashMap();
Employee e = new Employee("Saral", "Trainer", 34000);
Employee e1 = new Employee("Sarall", "saral", 34090);
employeeMap.put("S", e);
employeeMap.put("S1", e);
System.out.println(employeeMap.size());
Set s = employeeMap.entrySet();
Iterator it = s.iterator();
while(it.hasNext())
{
Map.Entry m =(Map.Entry)it.next();
System.out.println(m.getKey()+"\t"+m.getValue());
}
but when I try to run it , I want to fetch the employee details but I GET DISPLAYED THE OBJECT ON SCREEN ...I want to see the employees value, Please advise me how to get values from employee object.
2
S CollectionsPrac.Employee#285c2854
S1 CollectionsPrac.Employee#285c2854
You need to override the toString method in your Employee class, for example:
public String toString() {
return name + " [" + job + "] - salary: " + salary;
}
By the way, you can replace:
Iterator it = s.iterator();
while(it.hasNext())
{
Map.Entry m =(Map.Entry)it.next();
System.out.println(m.getKey()+"\t"+m.getValue());
}
with
System.out.println(s.toString());
Unless you really want the output to be tab separated.
You need to override the toString() method of Employee
#Override pulic String toString() {
return name + " " + job;
}
First of all. Your hashcode is broken.
Try running this:
System.out.println("Should be false: " + (new Employee("Sara", "Trainer", 1).hashCode() == new Employee("Trainer", "Sara", 1).hashCode()));
If you are using and IDE (like eclipse) there is a function to generate equals and hashcode methods automatically and you would get something like this:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((job == null) ? 0 : job.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + salary;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (job == null) {
if (other.job != null)
return false;
} else if (!job.equals(other.job))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (salary != other.salary)
return false;
return true;
}
As for your main method.. You should try to learn some basics about generics (the stuff inside the <>). You don't need the nity grity details at first. Just learn how to use it with lists and maps.. It will make your life a lot easier. Especially since your using and IDE...
Here is a refactored version of your main method:
public static void main(String[] args)
{
Map<String, Employee> employeeMap = new HashMap<String, Employee>();
Employee e = new Employee("Saral", "Trainer", 34000);
Employee e1 = new Employee("Sarall", "saral", 34090);
employeeMap.put("S", e);
employeeMap.put("S1", e1);
System.out.println(employeeMap.size());
Set<Entry<String, Employee>> entrySet = employeeMap.entrySet();
for (Entry<String, Employee> entry: entrySet) {
System.out.println(entry.getKey()+"\t"+entry.getValue().name);
}
System.out.println("Should be false: " + (new Employee("Sara", "Trainer", 1).hashCode() == new Employee("Trainer", "Sara", 1).hashCode()));
}
Change this in
Iterator it = s.iterator();
while(it.hasNext())
{
Map.Entry m =(Map.Entry)it.next();
Employee empl = (Employee) m.getValue();
System.out.println(m.getKey()+"\t"+empl.name);
}
As you can see with the line
Employee empl = (Employee) m.getValue();
the value is "casted" to an Employee object, and you can start to work with empl variable and use all the Employee class methods and members.