How value is passed into user defined compare function in treeset - java

Here is a code of treeset of user defined object.
package com.java2novice.treeset;
import java.util.Comparator;
import java.util.TreeSet;
public class MyCompUserDefine {
public static void main(String a[]){
//By using name comparator (String comparison)
TreeSet<Empl> nameComp = new TreeSet<Empl>(new MyNameComp());
nameComp.add(new Empl("Ram",3000));
nameComp.add(new Empl("John",6000));
nameComp.add(new Empl("Crish",2000));
nameComp.add(new Empl("Tom",2400));
for(Empl e:nameComp){
System.out.println(e);
}
System.out.println("===========================");
//By using salary comparator (int comparison)
TreeSet<Empl> salComp = new TreeSet<Empl>(new MySalaryComp());
salComp.add(new Empl("Ram",3000));
salComp.add(new Empl("John",6000));
salComp.add(new Empl("Crish",2000));
salComp.add(new Empl("Tom",2400));
for(Empl e:salComp){
System.out.println(e);
}
}
}
class MyNameComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
return e1.getName().compareTo(e2.getName());
}
}
class MySalaryComp implements Comparator<Empl>{
#Override
public int compare(Empl e1, Empl e2) {
if(e1.getSalary() > e2.getSalary()){
return 1;
} else {
return -1;
}
}
}
class Empl{
private String name;
private int salary;
public Empl(String n, int s){
this.name = n;
this.salary = s;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getSalary() {
return salary;
}
public void setSalary(int salary) {
this.salary = salary;
}
public String toString(){
return "Name: "+this.name+"-- Salary: "+this.salary;
}
}
My question is when I am calling MyNameComp() or MySalaryComp() then I am just calling its constructor without passing any value. But how value or object of EMP1 class are passed by?

The TreeSet objects that you create are responsible for using the comparator you passed when instantiating it.
How the TreeSet does it should not concern you because it's an implementation detail. The TreeSet just guarantees that the comparator you provide will be used when necessary. You don't need to think about it... but just for the heck of it, let's look at the source (please mind that you should not rely on implementation details of any classes as they are free to change, when consuming an API, you can only be sure of what's an explicit part of the interface!)
Let's start with the TreeSet constructor that takes a Comparator as an argument, this is what you're calling when you create your TreeSet instances in the examples provided
public More ...TreeSet(Comparator<? super E> comparator) {
this(new TreeMap<E,Object>(comparator));
}
We can see that the constructor uses the comparator to instantiate a TreeMap calls another TreeSet constructor. The TreeMap created here will be used to store the items in the TreeSet.
Let's leave it at that without inspecting what happens inside the TreeMap. We just need to know that the TreeMap is what actually stores the items. This knowledge will come in handy when we take a look at what happens when you add elements.
You're inserting all items using the TreeSet#add method, which uses the same map that got created when you called the constructor.
public boolean More ...add(E e) {
return m.put(e, PRESENT)==null;
}
The m object is the TreeMap instantiated inside the constructor. Since we know it's a TreeMap and that the put method is used, we can have a look at what it does.
Here's the implementation of TreeMap#put
This method uses a comparator that, upon closer inspection, turns out to be the same one that was used when creating the TreeMap in the TreeSet constructor.
public V More ...put(K key, V value) {
Entry<K,V> t = root;
if (t == null) {
// TBD:
// 7: (coll) Adding null to an empty TreeSet should
// throw NullPointerException
//
// compare(key, key); // type check
root = new Entry<K,V>(key, value, null);
size = 1;
modCount++;
return null;
}
int cmp;
Entry<K,V> parent;
// split comparator and comparable paths
Comparator<? super K> cpr = comparator;
if (cpr != null) {
do {
parent = t;
cmp = cpr.compare(key, t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
else {
if (key == null)
throw new NullPointerException();
Comparable<? super K> k = (Comparable<? super K>) key;
do {
parent = t;
cmp = k.compareTo(t.key);
if (cmp < 0)
t = t.left;
else if (cmp > 0)
t = t.right;
else
return t.setValue(value);
} while (t != null);
}
Entry<K,V> e = new Entry<K,V>(key, value, parent);
if (cmp < 0)
parent.left = e;
else
parent.right = e;
fixAfterInsertion(e);
size++;
modCount++;
return null;
}
This is a little complicated and you'd have to read through the rest of the implementation to gain a complete understanding of what's happening here but it's clearly visible that the provided comparator gets used.
The bottom line here, however, is that this should not matter to you or your code as the client of the collections API. You should only rely on what's explicitly stated in the Javadoc of the public or protected methods.
You can take a look at the JDK 8 version to see that the internals have changed (although very slightly)
The reason you can be sure that a TreeMap and the provided Comparator will be used is because it's part of TreeSet's API. To quote the TreeSet Javadoc:
(a TreeSet is) A NavigableSet implementation based on a TreeMap. The elements are ordered using their natural ordering, or by a Comparator provided at set creation time, depending on which constructor is used.
Changing any of these things would break the contract.

TreeSet keeps its elements sorted. If you provide a comparator, it uses that custom comparator (in your case MyNameComp() or MySalaryComp()) to compare and sort them. You dont need to call anything, TreeSet will handle it internally.

Related

Hash Set add method is not working fine

I wrote a dummy program , that adds object in Hash Set. I created a class Car that has capacity of 5 people.
Now issue is i got different out put from different Main programs .
Kindly find the 2-Main programs below.
First Main Program is
public class Main_1 {
static int counter = 0;
public static void main(String args[]) {
Car car = new Car();
for (int i = 0; i < 20; i++) {
car.add(new Person());
}
car.done();
}
}
The out put of Main_1 is : Exception in thread "main" java.lang.IllegalStateException: I'm full
at Car.add(Car.java:10)
at Main_1.main(Main_1.java:8)
Second Main program is
public class Main_2 {
static int counter = 0;
static Car car = new Car();
public static void main(String args[]) {
car.add(new RecursivePerson());
car.done();
}
static class RecursivePerson extends Person {
public int hashCode() {
if (++counter < 20) {
car.add(new RecursivePerson());
}
return super.hashCode();
}
}
}
The out put of Main_2 is I'm a car with 20 people!
Below is the business logic of my program.
import java.util.HashSet;
import java.util.Set;
public class Car {
private static final int CAPACITY = 5;
private Set<Person> people = new HashSet<Person>();
public synchronized void add(Person p) {
if (people.size() >= CAPACITY) {
throw new IllegalStateException("I'm full");
} else {
people.add(p);
}
}
public synchronized void done() {
if (people.size() == 20) {
// The goal is to reach this line
System.out.println("I'm a car with 20 people!");
}
}
}
class Person {
}
Can some one tell my why java is behaving like this.
The difference is because of the way that a HashSet works: if you add an new element to it, it first checks if the object is already in the set, and if it isn't, it adds this to the set. In order to check if the object is in the set, it call hashCode() on the object.
Your second program is specifically designed to bypass the capacity check of the car. You override hashCode() in the objects you add to the hashset. This method is called by the HashSet.add method, but before the object was actually added to the set. In the overridden hashCode() method you add the additional elements to the set. That is, if Car.add() is called, the size of the hash set is always 0, and the capacity check will always pass.
HashSets are implemented using a HashMap. Let us have a look at the source HashSet's source for add, according to GrepCode:
public boolean add(E e)
{
return map.put(e, PRESENT)==null;
}
Let us follow this to the put implementation in HashMap, according to GrepCode:
public V More ...put(K key, V value)
{
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode());
int i = indexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next)
{
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
{
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
}
modCount++;
addEntry(hash, key, value, i);
}
Your object is added in the last line with the use of addEntry. However, hashCode is called in the 3rd line before the entry is added; in the end, this cause put to be called again. Because your hashCode method adds until you have 20 element the size of the set is 20 in the end.
It is because in Main_2 you are calling add recursively. The initial call to .add() method will not return to actually increment the size of people list. So, people.size() so it will always return 0, altough you added a lot of elements there.
if you do a little debugging, you will see the callstack after a couple of iterations in Main_2 looks like this:

Is it possible to enter duplicate value in HashSet?

I am trying to add duplicate values in HashSet by modifying its hashCode() and equals() method()?
I tried below code
public class dupSet {
static Set set= new HashSet();
#Override
public int hashCode() {
return (int) (100*Math.random());
}
#Override
public boolean equals(Object obj) {
return false;
}
public static void main(String[] args) throws ParseException {
set.add("a");
set.add("b");
set.add("a");
System.out.println(set);
}
}
As per my understanding if for two duplicate of "a" HashSet will first get hashCode() to get proper bucket and then check value of equals() if equals returns true then it will not add but if it return false then it will add.
So for adding duplicate value to my Set I override equals() which always return false but still set is not allowing duplicate values?
You hashCode method returns always zero. Have a look at the range of Math.random().
Second, you do not override equals and hashCode of the elements you add. You actually add a String. To make things work, you must implement a class and add instances of that class to you HashSet. The implemented class needs to override the equals and hashSet method, not the main class.
Third, as stated in the comments, you shouldn't do what you are doing. What you realy want is a ArrayList. By implementing the equals and hashCode methods this way, a fundamental contract is broken.
I read source code and from that I am able to understand how its work
so need some help
First of all
Set is a collection of well defined and distinct objects
So there is no question of adding duplicates values. But if you are interested in understanding how java achieve/implement this constraint , then you can start digging in the source code.
A HashSet is backed by HashMap which mean that it delegates it operations like add, remove, etc. to HashMap .Now When you call set.add("a"); then
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
is called, which in turn calls HashMap#put
public V put(K key, V value) {
return putVal(hash(key), key, value, false, true);
}
The put method first calcuates the hash code of the object using
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
Once the hashCode is calculated the it calls
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict)
inside this method , it put the value because this condition
if ((p = tab[i = (n - 1) & hash]) == null)
is true and it then increments the modCount(which stores the number of times the HashMap has been structurally modified), checks if we need to resize the map and then call afterNodeInsertion and returns null
Now when you call set.add("b"); then the same logic runs again but this time the condition inside final V putVal method
if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k))))
holds true and due to this , the code
if (e != null) { // existing mapping for key
V oldValue = e.value;
if (!onlyIfAbsent || oldValue == null)
e.value = value;
afterNodeAccess(e);
return oldValue;
}
detects the existing mapping and thus return the oldValue . Hence preventing adding duplicate value.
You want the objects in the Set to include duplicates I assume (if just for curiosity keep reading, otherwise just choose other collection. this might help)
Let me make some corrections:
public class DupSet<E extends Comparable<E>>{
private Set<E> mySet = new HashSet<>();
//Implement add, remove and size
}
public class MyNeverEqualClass implements Comparable<MyNeverEqualClass>{
private static int stupidHash = 0;
private int num;
public MyNeverEqualClass(int num){
this.num = num;
}
#Override
public int compareTo(MyNeverEqualClass other){
double rnd = Math.random()*3 + 1
return (rnd > 1.5)? 1:-1;
}
#Override
public boolean equals(MyNeverEqualClass other){
return false;
}
#Override
public int hashCode(){
return stupidHash++;
}
}
public static void main(String[] args){
MyNeverEqualClass a = new MyNeverEqualClass(1);
MyNeverEqualClass b = new MyNeverEqualClass(1);
DupSet<MyNeverEqualClass> set = new DupSet<>();
set.add(a);
set.add(b);
}

Java TreeSet: remove and contains() not working

I have added some simple objects to a TreeSet, but when I call the TreeSet's remove() and contains() methods, they don't work. However, when I iterate over the set the object is printed. Employee objects shall be added to the set while the objects uniqueness is based on the objects name property. The Id property is the value that should be sorted, but which is not unique.
public class Employee {
private String name;
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// Two objects are considered equal if their names are equal
#Override
public boolean equals(Object o) {
if (o == null)
return false;
if (this == o)
return true;
if (o.getClass() == this.getClass()) {
Employee p = ( Employee) o;
if (p.getName() != null && this.getName() != null)
return this.getName().equals(p.getName());
else
return false;
} else {
return false;
}
}
}
//*******************************************************
public class EmployeeComp implements Comparator<Employee> {
// Sort Ids, but allow duplicates, hence this function is never returning 0
#Override
public int compare(Employee p1, Employee p2) {
int re = 0;
boolean scoreLt = (p1.getId() > p2.getId());
boolean scoreGt = (p1.getId() < p2.getId());
if(scoreLt)
re = -1;
if(scoreGt)
re = 1;
else
re = -1;
return re;
}
}
//*******************************************************
// Collection shall store unique names with ordered values like:
// Alex, 923
// Toni, 728
// Eddi, 232
// Peter, 232
// Eddi, 156 *** not allowed
import java.util.TreeSet;
public class Main {
private static EmployeeComp comp = new EmployeeComp();
private static TreeSet<Employee> employees = new TreeSet<Employee>(comp);
public static void main(String[] args) {
Employee p1 = new Employee();
p1.setName("Eddi");
p1.setId(232);
Employee p2 = new Employee();
p2.setName("Toni");
p2.setId(728);
Employee p3 = new Employee();
p3.setName("Peter");
p3.setId(232);
Employee p4 = new Employee();
p4.setName("Alex");
p4.setId(923);
employees.add(p1);
employees.add(p2);
employees.add(p3);
employees.add(p4);
// Here, contains() and remove() should check the object address
// and not perform their actions based on compareTo
}
}
A TreeSet inserts/removes according to the results of Comparable, not .equals()/.hashCode()!
This means, BTW, that the objects of your Set do implement Comparable (if they didn't, each time you'd have tried and inserted a member, you'd have been greeted with a ClassCastException).
To be more accurate, TreeSet is an implementation of SortedSet.
If you want a .equals()/.hashCode()-compatible set, use, for instance, a HashSet.
For the illustration, here is what happens with BigDecimal (posted a few hours ago here):
final BigDecimal one = new BigDecimal("1");
final BigDecimal oneDotZero = new BigDecimal("1.0");
final Set<BigDecimal> hashSet = new HashSet<>();
// BigDecimal implements Comparable of itself, so we can use that
final Set<BigDecimal> treeSet = new TreeSet<>();
hashSet.add(one);
hashSet.add(oneDotZero);
// hashSet's size is 2: one.equals(oneDotZero) == false
treeSet.add(one);
treeSet.add(oneDotZero);
// treeSet's size is... 1! one.compareTo(oneDotZero) == 0
To quote the javadoc for Comparable, it means that BigDecimal's .compareTo() is "not consistent with .equals()".
** EDIT ** As to what the OP wants:
a Collection which will not accept duplicate names;
a sorted view of that Collection which will sort against the user's id.
As mentioned above, you cannot have one collection which does both. The solution:
for the first, a HashSet;
for the second, a copy of that set into an ArrayList, then using Collections.sort().
This means .equals() and .hashCode() must act only on the name, while a custom Comparator will act on the id. The Comparator has no other choice but to be custom since it is a comparator which is not consisten with .equals() in any event.
As to the proposed code, there are problems.
First: Employee overrides .equals() but not .hashCode(). As such, Employee breaks the .equals() contract (one part of which is that if two objects are equal, they must have the same hashcode). What is more, .hashCode() is critical for HashSet to work at all. Fix:
#Override
public int hashCode()
{
return name == null ? 0 : name.hashCode();
}
#Override
public boolean equals(final Object obj)
{
if (obj == null)
return false;
if (this == obj)
return false;
if (!(obj instanceof Employee))
return false;
final Employee other = (Employee) obj;
return name == null ? other.name == null
: name.equals(other.name);
}
Second: the comparator is equally as broken as Employee since it breaks the Comparator contract (for any o1 and o2, o1.compareTo(o2) == - o2.compareTo(o1)). Fix:
public final class EmployeeComp
implements Comparator<Employee>
{
#Override
public int compare(final Employee o1, final Employee o2)
{
final int id1 = o1.getId(), id2 = o2.getId();
if (id1 == id2)
return 0;
return id1 > id2 ? 1 : -1;
}
}
Then, how to obtain a sorted copy of the set:
// "set" contains the unique employees
final List<Employee> sorted = new ArrayList<Employee>(set);
Collections.sort(list, new EmployeeComp());
DONE.
Your problem is conceptual.
If you want a sorted collection of unique objects: TreeSet
If you want a sorted collection were different objects can have the same comparison value for sorting purposes: PriorityQueue
Incidentally, the methods in a PriorityList are more suited to the usual needs of the second case than the ones on TreeSet. I used to think of it as TreeSet shortcomings. For example, to take the first item out of the collection.
Hope that helps :-)

Sorting custom data structure on Key in TreeMap

I am trying to sort a TreeMap on key. Key is some custom DataStructure having int, List, String, etc.
The member on which I am expecting a sort has some duplicates. Let's say that member is Rank. More than 1 object can have same rank.
Simplified version example:
NOTE: in the CompareTo method below 0 is not returned intentionally to NOT ignore duplicates.(Please correct me if this is not the right way to avoid duplicates)
import java.util.TreeMap;
public class TreeTest {
public static void main(String[] args) {
TreeMap<Custom,String> t = new TreeMap<Custom,String>();
Custom c1 = new Custom();
c1.setName("a");
c1.setRank(0);
Custom c2 = new Custom();
c2.setName("b");
c2.setRank(1);
Custom c3 = new Custom();
c3.setName("c");
c3.setRank(0);
t.put(c1, "first");
t.put(c2, "Second");
t.put(c3, "Third");
System.out.println(t.keySet());
for(Custom c:t.keySet()){
System.out.println(t.get(c));
}
}
}
And Custom Object
package com.example.ui;
public class Custom implements Comparable<Custom>{
int rank;
String name;
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + rank;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Custom other = (Custom) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (rank != other.rank)
return false;
return true;
}
// 0 is not returned intentionally to NOT ignore duplicates.
public int compareTo(Custom o) {
if(o.rank>this.rank)
return 1;
if(o.rank==this.rank)
return -1;
return -1;
}
}
Output::
[com.example.ui.Custom#fa0, com.example.ui.Custom#fbe, com.example.ui.Custom#f80]
null
null
null
Expected:
First, Second, Third based on Rank 0,1,0 respectively.
I looked at couple of examples on Google. Most of them were basic usage on TreeMap sort using keys or values with primitive datatypes, but none with duplicates when sorting member
is a part of custom key DataStructure.
Please help?
The problem is that your implementation of compareTo is not consistent with equals, which is required by TreeMap. From the API docs:
Note that the ordering maintained by a sorted map (whether or not an
explicit comparator is provided) must be consistent with equals if
this sorted map is to correctly implement the Map interface.
One possible consistent implementation would be to first compare by rank and then by name if the rank values are equal. For two instances of Custom with equal ranks and identical names you should not expect to be able to store them both as keys within the same Map - This violates the contract of Map.
public int compareTo(Custom o) {
int ret = this.rank - o.rank;
// Equal rank so fall back to comparing by name.
if (ret == 0) {
ret = this.name.compareTo(o.name);
}
return ret;
}
As mentioned, your implementation of equals and compareTo are not consistent with each other. If I read your question correctly, what you require is to preserve duplicates that have the same key. I'd recommend you to look into the TreeMultimap of the Google Guava collections. It creates set containers for each value object sothat different values having the same key are preserved.
e.g.
treeMultimap.put ("rank1", "Joe");
treeMultimap.put ("rank1", Jane");
treeMultimap.get ("rank1"); // Set("Joe","Jane");
The constrain in this data structure is that K,V pairs must be unique. That is, you can't insert ("rank1", "Joe") twice in the Multimap.
One important note: The reason why you see so many examples of Map, using simple types and, in particular, strings, is that keys in a map must be immutable. The equals and hashcode values of an object must not change in the time it's used as a key in a map. Translated to your example, you cannot do customObject.setRank(...) and updates a rank value when it's used as a key. To do so, you first need to remove the key and its values, update it and then insert it again.
You can also do it by implementing Comparator as anonymous inner type and override compare() to return desired comparison.
public class TreeMaps
{
public static void main(String[] args)
{
Custom c1 = new Custom(1,"A");
Custom c2 = new Custom(3,"C");
Custom c3 = new Custom(2,"B");
TreeMap<Custom , Integer > tree = new TreeMap<Custom, Integer> (new Comparator<Custom>() {
#Override
public int compare(Custom o1, Custom o2) {
return o1.rank - o2.rank;
}
});
tree.put(c1, 1);
tree.put(c2, 2);
tree.put(c3, 3);
System.out.println(tree);
}
}
class Custom
{
int rank ;
String name ;
public Custom(int rank , String name) {
this.rank = rank ;
this.name = name ;
}
#Override
public String toString()
{
return "Custom[" + this.rank + "-" + this.name + "]" ;
}
}

LinkedList.contains execution speed

Why Methode LinkedList.contains() runs quickly than such implementation:
for (String s : list)
if (s.equals(element))
return true;
return false;
I don't see great difference between this to implementations(i consider that search objects aren't nulls), same iterator and equals operation
Let's have a look at the source code (OpenJDK version) of java.util.LinkedList
public boolean contains(Object o) {
return indexOf(o) != -1;
}
public int indexOf(Object o) {
int index = 0;
if (o==null) {
/* snipped */
} else {
for (Entry e = header.next; e != header; e = e.next) {
if (o.equals(e.element))
return index;
index++;
}
}
return -1;
}
As you can see, this is a linear search, just like the for-each solution, so it's NOT asymptotically faster. It'd be interesting to see how your numbers grow with longer lists, but it's likely to be a constant factor slower.
The reason for that would be that this indexOf works on the internal structure, using direct field access to iterate, as opposed to the for-each which uses an Iterator<E>, whose methods must also additionally check for things like ConcurrentModificationException etc.
Going back to the source, you will find that the E next() method returned by the Iterator<E> of a LinkedList is the following:
private class ListItr implements ListIterator<E> {
//...
public E next() {
checkForComodification();
if (nextIndex == size)
throw new NoSuchElementException();
lastReturned = next;
next = next.next;
nextIndex++;
return lastReturned.element;
}
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
This is considerably "busier" than the e = e.next; in LinkedList.contains! The iterator() of a LinkedList is actually a ListIterator, which has richer features. They aren't needed in your for-each loop, but unfortunately you have to pay for them anyway. Not to mention all those defensive checks for ConcurrentModificationException must be performed, even if there isn't going to be any modification to the list while you're iterating it.
Conclusion
So yes, iterating a LinkedList as a client using a for-each (or more straightforwardly, using its iterator()/listIterator()) is more expensive than what the LinkedList itself can do internally. This is to be expected, which is why contains is provided in the first place.
Working internally gives LinkedList tremendous advantage because:
It can cut corners in defensive checks since it knows that it's not violating any invariants
It can take shortcuts and work with its internal representations
So what can you learn from this? Familiarize yourself with the API! See what functionalities are already provided; they're likely to be faster than if you've had to duplicate them as a client.
I decided to test this and came out with some interesting result
import java.util.LinkedList;
public class Contains {
private LinkedList<String> items = new LinkedList<String>();
public Contains(){
this.addToList();
}
private void addToList(){
for(int i=0; i<2000; i++){
this.items.add("ItemNumber" + i);
}
}
public boolean forEachLoop(String searchFor){
for(String item : items){
if(item.equals(searchFor))
return true;
}
return false;
}
public boolean containsMethod(String searchFor){
if(items.contains(searchFor))
return true;
return false;
}
}
and a JUnit testcase:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class ContainsTest {
#Test
public void testForEachLoop(){
Contains c = new Contains();
boolean result = c.forEachLoop("ItemNumber1758");
assertEquals("Bug!!", true, result);
}
#Test
public void testContainsMethod(){
Contains c = new Contains();
boolean result = c.containsMethod("ItemNumber1758");
assertEquals("Bug!!", true, result);
}
}
This funny thing is when I run the JUnit test the results are :
- testForEachLoop() - 0.014s
- testContainsMethod() - 0.025s
Is this true or I am doing something wrong ?

Categories