diff --git a/pom.xml b/pom.xml
index dbb5b78c935181452519a4755237d89d6d951252..310f993aad0c25e98b60e6a90dc1bbf5a95cc92b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,10 +3,10 @@
 	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>cz.vsb.fei.efrei</groupId>
-	<artifactId>efrei-lab03</artifactId>
+	<artifactId>efrei-lab04</artifactId>
 	<version>0.0.1-SNAPSHOT</version>
 
-	<name>efrei-lab03</name>
+	<name>efrei-lab04</name>
 
 	<packaging>jar</packaging>
 
diff --git a/src/main/java/cz/vsb/fei/efrei/lab03/DangerWorld.java b/src/main/java/cz/vsb/fei/efrei/lab03/DangerWorld.java
deleted file mode 100644
index 877827935a2469941fbd3cca0492cd39deffa0ff..0000000000000000000000000000000000000000
--- a/src/main/java/cz/vsb/fei/efrei/lab03/DangerWorld.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package cz.vsb.fei.efrei.lab03;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Random;
-import java.util.Scanner;
-
-public class DangerWorld {
-	private static final Random RANDOM = new Random();
-
-	public static void main(String[] args) {
-		List<Fighter> fighters = new ArrayList<>();
-
-		generateMonstersAndHeros(fighters);
-		
-		WorkWithCollections.playWithCollections(fighters);
-
-	}
-
-	private static void generateMonstersAndHeros(List<Fighter> fighters) {
-		try (Scanner s = new Scanner(System.in)) {
-			System.out.println("Type name of monster:");
-			String name = s.next();
-	
-			Monster monster = new Monster(name);
-			fighters.add(monster);
-		} catch (Exception e) {
-			System.out.println("Cannot properlly read name from STDIN. Continu without named monster");
-		}
-		fighters.add(new Monster("King"));
-		fighters.add(new Monster("Queen"));
-		fighters.add(new Monster("Fairy"));
-		fighters.add(new Hero("Shrek"));
-		fighters.add(new Hero("Cinderela"));
-	
-		int countOfHeros = RANDOM.nextInt(200);
-		for (int i = 0; i < countOfHeros; i++) {
-			fighters.add(new Hero(Utils.generateHeroName()));
-		}
-	
-		int countOfMonsters = RANDOM.nextInt(250);
-		for (int i = 0; i < countOfMonsters; i++) {
-			fighters.add(new Monster(Utils.generateMonsterName()));
-		}
-	}
-
-	
-	
-	
-}
diff --git a/src/main/java/cz/vsb/fei/efrei/lab03/WorkWithCollections.java b/src/main/java/cz/vsb/fei/efrei/lab03/WorkWithCollections.java
deleted file mode 100644
index d7a8f7443502719cb4d1120efe809d6951db8183..0000000000000000000000000000000000000000
--- a/src/main/java/cz/vsb/fei/efrei/lab03/WorkWithCollections.java
+++ /dev/null
@@ -1,225 +0,0 @@
-package cz.vsb.fei.efrei.lab03;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-public class WorkWithCollections {
-
-	public static void playWithCollections(List<Fighter> fighters) {
-		calculateAverageStrenght(fighters);
-		calculateAverageLives(fighters);
-
-		System.out.println("=========================================================");
-		makeFights(fighters, 1000);
-		System.out.println("=========================================================");
-
-		calculateAverageLives(fighters);
-		System.out.println("=========================================================");
-
-		try {
-			removeDeadsCauseException(fighters);
-			printDeadAndlives(fighters);
-		} catch (Exception e) {
-			e.printStackTrace();
-			System.out.println("Continue! Expected exception");
-		}
-		System.out.println("=========================================================");
-
-		//use copy of list
-		int countDeath = removeDeadsUsingAnotherCollection(new ArrayList<>(fighters));
-		System.out.println("Number of deats:" + countDeath);
-		System.out.println("=========================================================");
-
-		//use copy of list
-		countDeath = removeDeadsUsingIndexWithMistakes(new ArrayList<>(fighters));
-		System.out.println("Number of deats:" + countDeath);
-		System.out.println("=========================================================");
-
-		//use copy of list
-		countDeath = removeDeadsUsingIndex(new ArrayList<>(fighters));
-		System.out.println("Number of deats:" + countDeath);
-		System.out.println("=========================================================");
-
-		countDeath = removeDeadsUsingIterator(fighters);
-		System.out.println("Number of deats:" + countDeath);
-		System.out.println("=========================================================");
-
-
-		for (Fighter fighter2 : fighters) {
-			if (!fighter2.isAlive()) {
-				System.out.println("Fount dead fighter " + fighter2.getName());
-			}
-		}
-
-		Map<String, Integer> namesCountMap = new HashMap<>();
-		countFrequencyOfNames(fighters, namesCountMap);
-
-		printOutAllNamesAndTheirCount(namesCountMap);
-
-
-	}
-	
-	private static void makeFights(List<Fighter> fighters, int rounds) {
-		for (int i = 0; i < rounds; i++) {
-			Fighter fighter1 = fighters.get(Utils.RANDOM.nextInt(fighters.size()));
-			Fighter fighter2 = fighters.get(Utils.RANDOM.nextInt(fighters.size()));
-			try {
-				fighter1.attackedBy(fighter2);
-			} catch (AlreadyDeadException e) {
-				System.out.println("Ups! Fighter " + fighter2.getName() + " attack already dead " + fighter1.getName());
-			}
-		}
-	}
-
-	private static int removeDeadsCauseException(List<Fighter> fighters) {
-		int countDeath = 0;
-		List<Fighter> deads = new ArrayList<>();
-		//use foreach loop that use iterator 
-		for (Fighter fighter : fighters) {
-			if (!fighter.isAlive()) {
-				countDeath++;
-				/*cannot remove from collection which is iterated*/
-				fighters.remove(fighter);
-			}
-		}
-		fighters.removeAll(deads);
-		return countDeath;
-	}
-
-	private static int removeDeadsUsingAnotherCollection(List<Fighter> fighters) {
-		System.out.println("Remove using another collection");
-		printDeadAndlives(fighters);
-		int countDeath = 0;
-		List<Fighter> deads = new ArrayList<>();
-		for (Fighter fighter : fighters) {
-			if (!fighter.isAlive()) {
-				countDeath++;
-				deads.add(fighter);
-			}
-		}
-		fighters.removeAll(deads);
-		printDeadAndlives(fighters);
-		return countDeath;
-	}
-
-	private static int removeDeadsUsingIndexWithMistakes(List<Fighter> fighters) {
-		System.out.println("Remove using index with errors");
-		int countDeath = 0;
-		printDeadAndlives(fighters);
-		for (int i = 0; i < fighters.size(); i++) {
-			if (!fighters.get(i).isAlive()) {
-				countDeath++;
-				fighters.remove(i);
-			}
-		}
-		printDeadAndlives(fighters);
-		return countDeath;
-	}
-
-	private static int removeDeadsUsingIndex(List<Fighter> fighters) {
-		System.out.println("Remove using index");
-		int countDeath = 0;
-		printDeadAndlives(fighters);
-		for (int i = fighters.size() - 1; i >= 0; i--) {
-			if (!fighters.get(i).isAlive()) {
-				countDeath++;
-				fighters.remove(i);
-			}
-		}
-		printDeadAndlives(fighters);
-		return countDeath;
-	}
-
-	private static int removeDeadsUsingIterator(List<Fighter> fighters) {
-		System.out.println("Remove using Iterator");
-		printDeadAndlives(fighters);
-		int countDeath = 0;
-		Iterator<Fighter> iterator = fighters.iterator();
-		while (iterator.hasNext()) {
-			if (!iterator.next().isAlive()) {
-				iterator.remove();
-				countDeath++;
-			}
-		}
-		printDeadAndlives(fighters);
-		return countDeath;
-	}
-
-	private static void calculateAverageStrenght(List<Fighter> fighters) {
-		int sumStrenght = 0;
-		for (Fighter fighter : fighters) {
-			sumStrenght += fighter.getStrenght();
-		}
-		System.out.println("Average strenght of all fighters is " + sumStrenght / fighters.size());
-		int sumStrenghtOfHeroes = 0;
-		int numberOfHeroes = 0;
-		int sumStrenghtOfMonsters = 0;
-		int numberOfMonsters = 0;
-		for (Fighter fighter : fighters) {
-			if (fighter instanceof Monster) {
-				sumStrenghtOfMonsters += fighter.getStrenght();
-				numberOfMonsters++;
-			} else if (fighter instanceof Hero) {
-				sumStrenghtOfHeroes += fighter.getStrenght();
-				numberOfHeroes++;
-			}
-
-		}
-		System.out.println("Average strenght of all Heros is " + sumStrenghtOfHeroes / numberOfHeroes);
-		System.out.println("Average strenght of all Monsters is " + sumStrenghtOfMonsters / numberOfMonsters);
-	}
-
-	private static void calculateAverageLives(List<Fighter> fighters) {
-		int sumLives = 0;
-		for (Fighter fighter : fighters) {
-			sumLives += fighter.getLives();
-		}
-		System.out.println("Average lives of all fighters is " + sumLives / fighters.size());
-		int sumLivesOfHeroes = 0;
-		int numberOfHeroes = 0;
-		int sumLivesOfMonsters = 0;
-		int numberOfMonsters = 0;
-		for (Fighter fighter : fighters) {
-			if (fighter instanceof Monster) {
-				sumLivesOfMonsters += fighter.getLives();
-				numberOfMonsters++;
-			} else if (fighter instanceof Hero) {
-				sumLivesOfHeroes += fighter.getLives();
-				numberOfHeroes++;
-			}
-
-		}
-		System.out.println("Average strenght of all Heros is " + sumLivesOfHeroes / numberOfHeroes);
-		System.out.println("Average strenght of all Monsters is " + sumLivesOfMonsters / numberOfMonsters);
-	}
-
-	private static void printDeadAndlives(List<Fighter> fighters) {
-		for (Fighter fighter : fighters) {
-			System.out.print(fighter.isAlive()?"a":"D");
-		}
-		System.out.println();
-	}
-
-	private static void countFrequencyOfNames(List<Fighter> fighters, Map<String, Integer> namesCountMap) {
-		for (Fighter fighter : fighters) {
-			if (namesCountMap.containsKey(fighter.getName())) {
-				Integer count = namesCountMap.get(fighter.getName());
-				int newCount = count + 1;
-				namesCountMap.put(fighter.getName(), newCount);
-			} else {
-				namesCountMap.put(fighter.getName(), 1);
-			}
-		}
-	}
-
-	private static void printOutAllNamesAndTheirCount(Map<String, Integer> namesCountMap) {
-		for (String name1 : namesCountMap.keySet()) {
-			int count = namesCountMap.get(name1);
-			System.out.println(name1 + ": " + count);
-		}
-	}
-
-}
diff --git a/src/main/java/cz/vsb/fei/efrei/lab03/AlreadyDeadException.java b/src/main/java/cz/vsb/fei/efrei/lab04/AlreadyDeadException.java
similarity index 90%
rename from src/main/java/cz/vsb/fei/efrei/lab03/AlreadyDeadException.java
rename to src/main/java/cz/vsb/fei/efrei/lab04/AlreadyDeadException.java
index dd46d7aeebcd7019df8c670885c8f65a50b32195..ce0958968ee55a9b03a1156d6328d9de87532a50 100644
--- a/src/main/java/cz/vsb/fei/efrei/lab03/AlreadyDeadException.java
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/AlreadyDeadException.java
@@ -1,4 +1,4 @@
-package cz.vsb.fei.efrei.lab03;
+package cz.vsb.fei.efrei.lab04;
 
 public class AlreadyDeadException extends Exception {
 
diff --git a/src/main/java/cz/vsb/fei/efrei/lab03/Fighter.java b/src/main/java/cz/vsb/fei/efrei/lab04/Fighter.java
similarity index 88%
rename from src/main/java/cz/vsb/fei/efrei/lab03/Fighter.java
rename to src/main/java/cz/vsb/fei/efrei/lab04/Fighter.java
index 442d9c99fb302fe030ccf31cc4f4d5435df5f5d1..f5b13d2cd0bfc2191d8b9eca9059b9321985a2b0 100644
--- a/src/main/java/cz/vsb/fei/efrei/lab03/Fighter.java
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/Fighter.java
@@ -1,4 +1,4 @@
-package cz.vsb.fei.efrei.lab03;
+package cz.vsb.fei.efrei.lab04;
 
 public interface Fighter {
 
diff --git a/src/main/java/cz/vsb/fei/efrei/lab03/Hero.java b/src/main/java/cz/vsb/fei/efrei/lab04/Hero.java
similarity index 83%
rename from src/main/java/cz/vsb/fei/efrei/lab03/Hero.java
rename to src/main/java/cz/vsb/fei/efrei/lab04/Hero.java
index d0d09a385733d7a9cc1fdf5182e57d5b76fd3e73..09bb8bf489ff70ac13471ba991bc5cd2d8ada7ea 100644
--- a/src/main/java/cz/vsb/fei/efrei/lab03/Hero.java
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/Hero.java
@@ -1,13 +1,14 @@
-package cz.vsb.fei.efrei.lab03;
+package cz.vsb.fei.efrei.lab04;
 
+import java.util.Objects;
 import java.util.Random;
 
 public class Hero implements Fighter{
 
 	private static final Random RANDOM = new Random();
 
-	private String name;
-	private int strenght;
+	protected String name;
+	protected int strenght;
 	private int lives;
 
 	public Hero(String name, int strenght) {
@@ -22,7 +23,7 @@ public class Hero implements Fighter{
 	}
 
 	public Hero(String name) {
-		this(name, RANDOM.nextInt(50) + 50);
+		this(name, RANDOM.nextInt(5000) + 50);
 	}
 
 	@Override
@@ -56,7 +57,7 @@ public class Hero implements Fighter{
 
 	@Override
 	public String toString() {
-		return "Hero " + name + "(" + strenght + ") - has " + lives + " lives.";
+		return "Hero " + name + "(" + strenght + ")";
 	}
 
 }
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEquals.java b/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEquals.java
new file mode 100644
index 0000000000000000000000000000000000000000..61aa3b71e327472e376bb460b497364778253bf6
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEquals.java
@@ -0,0 +1,27 @@
+package cz.vsb.fei.efrei.lab04;
+
+import java.util.Objects;
+
+public class HeroWithEquals extends Hero {
+
+	public HeroWithEquals(String name) {
+		super(name);
+	}
+
+	public HeroWithEquals(String name, int strenght) {
+		super(name, strenght);
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Hero other = (Hero) obj;
+		return Objects.equals(name, other.name);
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEqualsAndBadHashcode.java b/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEqualsAndBadHashcode.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8287294a41ca10968fdb44a3926ab6f6e02e17a
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEqualsAndBadHashcode.java
@@ -0,0 +1,32 @@
+package cz.vsb.fei.efrei.lab04;
+
+import java.util.Objects;
+
+public class HeroWithEqualsAndBadHashcode extends Hero {
+
+	public HeroWithEqualsAndBadHashcode(String name) {
+		super(name);
+	}
+
+	public HeroWithEqualsAndBadHashcode(String name, int strenght) {
+		super(name, strenght);
+	}
+	
+	@Override
+	public int hashCode() {
+		return Objects.hash(strenght);
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Hero other = (Hero) obj;
+		return Objects.equals(name, other.name) && strenght == other.strenght;
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEqualsAndConstantHashcode.java b/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEqualsAndConstantHashcode.java
new file mode 100644
index 0000000000000000000000000000000000000000..c73a9ce152cb46338a0c2119e64fc69324ff2626
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEqualsAndConstantHashcode.java
@@ -0,0 +1,32 @@
+package cz.vsb.fei.efrei.lab04;
+
+import java.util.Objects;
+
+public class HeroWithEqualsAndConstantHashcode extends Hero {
+
+	public HeroWithEqualsAndConstantHashcode(String name) {
+		super(name);
+	}
+
+	public HeroWithEqualsAndConstantHashcode(String name, int strenght) {
+		super(name, strenght);
+	}
+	
+	@Override
+	public int hashCode() {
+		return 1;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Hero other = (Hero) obj;
+		return Objects.equals(name, other.name) && strenght == other.strenght;
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEqualsAndHashcode.java b/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEqualsAndHashcode.java
new file mode 100644
index 0000000000000000000000000000000000000000..11d43f982459cfbccb170fdf60ce032fc19bb285
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/HeroWithEqualsAndHashcode.java
@@ -0,0 +1,32 @@
+package cz.vsb.fei.efrei.lab04;
+
+import java.util.Objects;
+
+public class HeroWithEqualsAndHashcode extends Hero {
+
+	public HeroWithEqualsAndHashcode(String name) {
+		super(name);
+	}
+
+	public HeroWithEqualsAndHashcode(String name, int strenght) {
+		super(name, strenght);
+	}
+	
+	@Override
+	public int hashCode() {
+		return Objects.hash(name, strenght);
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Hero other = (Hero) obj;
+		return Objects.equals(name, other.name) && strenght == other.strenght;
+	}
+
+}
diff --git a/src/main/java/cz/vsb/fei/efrei/lab03/Monster.java b/src/main/java/cz/vsb/fei/efrei/lab04/Monster.java
similarity index 97%
rename from src/main/java/cz/vsb/fei/efrei/lab03/Monster.java
rename to src/main/java/cz/vsb/fei/efrei/lab04/Monster.java
index 2817aa6e635985ade1186257835fd257ce038d1c..7b2edf0cfdd96f089a95538f6b73eeaf1844628e 100644
--- a/src/main/java/cz/vsb/fei/efrei/lab03/Monster.java
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/Monster.java
@@ -1,4 +1,4 @@
-package cz.vsb.fei.efrei.lab03;
+package cz.vsb.fei.efrei.lab04;
 
 import java.util.Random;
 
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/Stopwatch.java b/src/main/java/cz/vsb/fei/efrei/lab04/Stopwatch.java
new file mode 100644
index 0000000000000000000000000000000000000000..a3e651f7baab045305ef4c8425d8a2ea555e195c
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/Stopwatch.java
@@ -0,0 +1,34 @@
+package cz.vsb.fei.efrei.lab04;
+
+public class Stopwatch {
+
+	private long startTime;
+	private long endTime;
+
+	public void start() {
+		startTime = System.nanoTime();
+	}
+
+	public void stop() {
+		endTime = System.nanoTime();
+	}
+
+	public long getDuration() {
+		return endTime - startTime;
+	}
+
+	public String formatDuration() {
+		long timeDuration = getDuration();
+		long timeNanoSec = timeDuration % 1000;
+		timeDuration = timeDuration / 1000;
+		long timeMicroSec = timeDuration % 1000;
+		timeDuration = timeDuration / 1000;
+		long timeMiliSec = timeDuration % 1000;
+		timeDuration = timeDuration / 1000;
+		long timeSec = timeDuration % 60;
+		timeDuration = timeDuration / 60;
+		long timeMinutes = timeDuration;
+		return String.format("%2dmin %2ds %3dms %3dus %3dns", timeMinutes, timeSec, timeMiliSec, timeMicroSec,
+				timeNanoSec);
+	}
+}
diff --git a/src/main/java/cz/vsb/fei/efrei/lab03/Utils.java b/src/main/java/cz/vsb/fei/efrei/lab04/Utils.java
similarity index 97%
rename from src/main/java/cz/vsb/fei/efrei/lab03/Utils.java
rename to src/main/java/cz/vsb/fei/efrei/lab04/Utils.java
index 7aba91aec9806d3f146bc598e74b217c8ee89173..3ab90ed3ceb4418143338c2a235641363a345299 100644
--- a/src/main/java/cz/vsb/fei/efrei/lab03/Utils.java
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/Utils.java
@@ -1,4 +1,4 @@
-package cz.vsb.fei.efrei.lab03;
+package cz.vsb.fei.efrei.lab04;
 
 import java.util.Arrays;
 import java.util.List;
diff --git a/src/main/java/cz/vsb/fei/efrei/lab04/WorldOfCollections.java b/src/main/java/cz/vsb/fei/efrei/lab04/WorldOfCollections.java
new file mode 100644
index 0000000000000000000000000000000000000000..f33777d7e23238d077bd44be409709f7b335efc2
--- /dev/null
+++ b/src/main/java/cz/vsb/fei/efrei/lab04/WorldOfCollections.java
@@ -0,0 +1,177 @@
+package cz.vsb.fei.efrei.lab04;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+public class WorldOfCollections {
+	private static final Random RANDOM = new Random();
+
+	public static void main(String[] args) {
+		useSetToStoreObjectWithoutHashCodeAndEquals();
+		useSetToStoreObjectWithEqualsOnlyForName();
+		useSetToStoreObjectWithEqualsAndHashCode();
+		useSetToStoreObjectWithEqualsBasedOnNameAndBadHashCode();
+		useSetToStoreObjectWithEqualsAndConstantHashCode();
+		System.out.println("==========================================================================================");
+		performanceForUseSetToStoreObjectWithEqualsAndHashCode();
+		performanceForUseSetToStoreObjectWithEqualsAndConstantHashCode();
+		System.out.println("==========================================================================================");
+		performanceForAddIntoArrayList();
+		performanceForAddIntoLinkedList();
+		performanceForInsertIntoArrayList();
+		performanceForInsertIntoLinkedList();
+		
+	}
+
+	private static void testObjectAnHashSet(Set<Fighter> setOfFighters, Hero king1, Hero king2) {
+		setOfFighters.add(king1);
+		System.out.println("Is king1 " + king1 + " in set: " + setOfFighters.contains(king1));
+		System.out.println("Is king1 " + king1 + " equal to king2 " + king2 + ": " + king1.equals(king2));
+		System.out.println("Is king2 in set: " + setOfFighters.contains(king2));
+		setOfFighters.add(king2);
+		System.out.println("Is king2 in set after add: " + setOfFighters.contains(king2));
+		System.out.println("Size of set is: " + setOfFighters.size());
+	}
+
+	public static void useSetToStoreObjectWithoutHashCodeAndEquals() {
+		Set<Fighter> setOfFighters = new HashSet<>();
+		Hero king1 = new Hero("King", 66);
+		Hero king2 = new Hero("King", 66);
+		System.out.println("=====Use HashSet to Store Object Without HashCode And Equals================================");
+		testObjectAnHashSet(setOfFighters, king1, king2);
+		System.out.println("Each object is different (different palces in memory) even look same!");
+	}
+
+
+	public static void useSetToStoreObjectWithEqualsOnlyForName() {
+		Set<Fighter> setOfFighters = new HashSet<>();
+		Hero king1 = new HeroWithEquals("King", 66);
+		Hero king2 = new HeroWithEquals("King", 42);
+		System.out.println("=====Use HashSet to Store Object Only With Equals================================");
+		testObjectAnHashSet(setOfFighters, king1, king2);
+		System.out.println("Object are equals because of same name, but not found in set because of worng hashcode!");
+	}
+
+	public static void useSetToStoreObjectWithEqualsAndHashCode() {
+		Set<Fighter> setOfFighters = new HashSet<>();
+		Hero king1 = new HeroWithEqualsAndHashcode("King", 66);
+		Hero king2 = new HeroWithEqualsAndHashcode("King", 66);
+		System.out.println("=====Use HashSet to Store Object Only With Equals================================");
+		testObjectAnHashSet(setOfFighters, king1, king2);
+		System.out.println("It's work!");
+	}
+
+	public static void useSetToStoreObjectWithEqualsBasedOnNameAndBadHashCode() {
+		Set<Fighter> setOfFighters = new HashSet<>();
+		Hero king1 = new HeroWithEqualsAndBadHashcode("King", 66);
+		Hero king2 = new HeroWithEqualsAndBadHashcode("King", 42);
+		System.out.println("=====Use HashSet to Store Object With Equals and BAD hashcode================================");
+		testObjectAnHashSet(setOfFighters, king1, king2);
+		System.out.println("It does'n work!");
+		System.out.println("Object are equals because of same name, but not found in set because of worng hashcode calculated from strenght!");
+	}
+
+	public static void useSetToStoreObjectWithEqualsAndConstantHashCode() {
+		Set<Fighter> setOfFighters = new HashSet<>();
+		Hero king1 = new HeroWithEqualsAndConstantHashcode("King", 66);
+		Hero king2 = new HeroWithEqualsAndConstantHashcode("King", 66);
+		System.out.println("=====Use HashSet to Store Object With Equals and constant hashcode================================");
+		testObjectAnHashSet(setOfFighters, king1, king2);
+		System.out.println("It's work!");
+	}
+	
+	private static String mesureAndAdd(Collection<Hero> sourceOfHeros, Collection<Hero> tragetOfHeros) {
+		Stopwatch stopwatch = new Stopwatch();
+		stopwatch.start();
+		for (Hero hero : sourceOfHeros) {
+			tragetOfHeros.add(hero);
+		}
+		stopwatch.stop();
+		String duration = stopwatch.formatDuration();
+		return duration;
+	}
+
+	private static String mesureAndInsert(Collection<Hero> sourceOfHeros, List<Hero> tragetOfHeros) {
+		Stopwatch stopwatch = new Stopwatch();
+		stopwatch.start();
+		for (Hero hero : sourceOfHeros) {
+			tragetOfHeros.add(0, hero);
+		}
+		stopwatch.stop();
+		String duration = stopwatch.formatDuration();
+		return duration;
+	}
+
+	public static void performanceForUseSetToStoreObjectWithEqualsAndHashCode() {
+		int countOfHeros = 20000;
+		List<Hero> heros = new ArrayList<>(countOfHeros);
+		for (int i = 0; i < countOfHeros; i++) {
+			heros.add(new HeroWithEqualsAndHashcode(Utils.generateHeroName()));
+		}
+		Set<Hero> setOfHeros = new HashSet<>();
+		String duration = mesureAndAdd(heros, setOfHeros);
+		System.out.println("Adding " + countOfHeros + " heros with correct hashcode and equals into set take " + duration);
+	}
+
+
+	public static void performanceForUseSetToStoreObjectWithEqualsAndConstantHashCode() {
+		int countOfHeros = 20000;
+		List<Hero> heros = new ArrayList<>(countOfHeros);
+		for (int i = 0; i < countOfHeros; i++) {
+			heros.add(new HeroWithEqualsAndConstantHashcode(Utils.generateHeroName()));
+		}
+		Set<Hero> setOfHeros = new HashSet<>();
+		String duration = mesureAndAdd(heros, setOfHeros);
+		System.out.println("Adding " + countOfHeros + " heros with constant hashcode into set take " + duration);
+	}
+
+
+	public static void performanceForAddIntoArrayList() {
+		int countOfHeros = 500000;
+		List<Hero> heros = new ArrayList<>(countOfHeros);
+		for (int i = 0; i < countOfHeros; i++) {
+			heros.add(new HeroWithEqualsAndConstantHashcode(Utils.generateHeroName()));
+		}
+		List<Hero> arrayListOfHeros = new ArrayList<>();
+		String duration = mesureAndAdd(heros, arrayListOfHeros);
+		System.out.println("Adding " + countOfHeros + " heros to end of ArrayList take " + duration);
+	}
+
+	public static void performanceForAddIntoLinkedList() {
+		int countOfHeros = 500000;
+		List<Hero> heros = new ArrayList<>(countOfHeros);
+		for (int i = 0; i < countOfHeros; i++) {
+			heros.add(new HeroWithEqualsAndConstantHashcode(Utils.generateHeroName()));
+		}
+		List<Hero> arrayListOfHeros = new LinkedList<>();
+		String duration = mesureAndAdd(heros, arrayListOfHeros);
+		System.out.println("Adding " + countOfHeros + " heros to end of LinkedList take " + duration);
+	}
+
+	public static void performanceForInsertIntoArrayList() {
+		int countOfHeros = 500000;
+		List<Hero> heros = new ArrayList<>(countOfHeros);
+		for (int i = 0; i < countOfHeros; i++) {
+			heros.add(new HeroWithEqualsAndConstantHashcode(Utils.generateHeroName()));
+		}
+		List<Hero> arrayListOfHeros = new ArrayList<>();
+		String duration = mesureAndInsert(heros, arrayListOfHeros);
+		System.out.println("Inserting " + countOfHeros + " heros at beginnig of ArrayList take " + duration);
+	}
+
+	public static void performanceForInsertIntoLinkedList() {
+		int countOfHeros = 500000;
+		List<Hero> heros = new ArrayList<>(countOfHeros);
+		for (int i = 0; i < countOfHeros; i++) {
+			heros.add(new HeroWithEqualsAndConstantHashcode(Utils.generateHeroName()));
+		}
+		List<Hero> arrayListOfHeros = new LinkedList<>();
+		String duration = mesureAndInsert(heros, arrayListOfHeros);
+		System.out.println("Inserting " + countOfHeros + " heros at beginnig of LinkedList take " + duration);
+	}
+}