New in Java (Map and Set) - java

Can Any help me and Check my answer
(a) Declare a private instance variable (Attribute) called HouseMap which should hold an unsorted map with integer keys and string values.
Private Map< Integer, String> HouseMap = new HashMap<Integer, String>();
(b) Write a zero-argument constructor of HouseCatalogue that initializes HouseMap to an empty map.
houseMap = new HashMap<Integer, String>();
(c) Write an instance method called addHouse() for the HouseCatalogue class that takes no arguments, and returns no value. This method should simply enter the four entries shown above into the HouseMap.
Public void addHouse()
{
HouseMap.put(101," adison Sas") ;
HouseMap.put(103," FourSeasons") ;
HouseMap.put(105," Hayat Regency ");
HouseMap.put(107," Concord al-Salam ") ;
}
(d) Write an instance method called printHouse() for the HouseCatalogue class that takes an integer argument, and return a string value. This method should print the value (House name) of the area code that is equal to integer argument and return it. Otherwise it will return null.
Public string printHouse( int area)
{
for(Integer eachcode : HouseMap.keySet())
{
if ( HouseMap.keySet()== area)
{
System.out.println("House name is"+ HouseMap.get(eachcode));
}
}
}
or
public static void printHouse( int area)
{
for(Map.Entry<Integer,String> entry : houseMap.entrySet())
{
if (entry.getKey().equals(area))
{
System.out.println("House name is"+ entry.getValue());
//return entry.getValue(); // return it
}
}
}

(a) Lower case letter for private and no new HashMap() needed when declaring. Normally when useing java convensions you use camelcase when declaring your variasbles (houseMap) but it's fine.
private Map<Integer, String> HouseMap;
(b) You have declared your variable with HouseMap not houseMap (see (a) camelcase) so initializing it needs the same variable:
HouseMap = new HashMap<Integer, String>();
(c) Seems fine
(d) Hum, don't see the point in the method, it should both print the value and return it.. well.. first off public lower case letters again, String with a big letter (name of the class` and then the implementation:
public String printHouse(int area) {
if (HouseMap.containsKey(area)) {
String name = HouseMap.get(area);
System.out.println("The house with the area code " + area +
" is " + name));
return name;
}
return null;
}

a) only declare the variable - do not initialize it
b) ok
c) ok
d) in a map you have random access. look at Map#get(Integer) API. you don't need to iterate over the entry set

Since the key of a map is unique, you can simplify the last method as follows:
public static void printHouse( int area)
{
String name = houseMap.get(area); // May return null
System.out.println("House name is " + name);
return name;
}

public and private must be written with a lowercase p everywhere.
You should show the entire constructor, not just the code that goes in it.
Fix your indentation. Use the same amount of indentation for every level, and make sure that everything lines up neatly.
When you use a foreach loop like for (Integer eachcode: HouseMap.keySet()), the iteration variable is eachcode. This is the value that you should compare to area, because that's what the integer is. You don't want to compare the supplied to all of the area codes taken as a single unit (those aren't the same kind of thing); you want to compare it to each area code in turn.
But you don't want to write that loop at all. The point of a HashMap is to let you look up the value, given the key. That is what .get() does. You have the key: it is area. So all you need to do is look it up: System.out.println("House name is " + HouseMap.get(area)).
You also need to return the name that you looked up, not just print it, and you need to check that the name is there (use .contains()) before printing.
It looks like somebody else commented your code to say "you also forgot to return it". Did you try talking to this person, or reading the comments?

Just a hint for the last one:
(d) Write an instance method called
An instance method is not a static method, you have to remove the static keyword in your second (d) method...

Thanks alot for every body
public static String printHouse(int
code) {
if (houseMap.containsKey(code))
{
String name = houseMap.get(coe);
System.out.println(code+ " : " + name);
return name;
} else{
System.out.println("null");
return null; }

Related

How to traverse through HashSet of objects and print the String value of each object in ToString method?

HashSet<Soldier> soldiers; // it has name, rank, description
#Override
public String toString(){
return "Team: " + teamName + "\n" + "Rank: " + getRanking(soldiers) + "\n"
+ "Team Members Names are: "+"\n" + soldiers.iterator().hasNext();
//last line doesn't work
// I also tried soldiers.forEach(System.out::println) but doesn't work
}
Can anyone please how I can print all the name from Hashset in overriden toString method. Thanks
If you use java 8. It's simple to do with stream API:
public class Test {
public static void main(String[] args) {
Set<String> strings = new HashSet<>();
strings.add("111");
strings.add("113");
strings.add("112");
strings.add("114");
String contactString = strings.stream().map(String::toString).collect(Collectors.joining(","));
}
}
If you want change a delimiter you should replace Collectiors.joining(",") code to what you need. See also documentation by StringJoiner
For your class Soldier which has method getName():
Set<Soldier> soldiers = new HashSet<>();
String soldierNames = soldiers.stream().map(Soldier::getName).collect(Collectors.joining("\n"));
You will get a next result:
Din
Mark
David
... values from the soldiers set
hasNext() does only return a boolean indicating if the Iterator is finished or not.
You still have to call next() (in a loop) to get the next value(s).
See: https://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html

how to get only one key in a HashMap with "similar" keys

I have an object "ObjectName" defined by String hostName and List serviceList.
two serviceLists might contain one or more of the same string.
Each string is the name of a method. There can't be methods with same name that do different things or methods with different names that do the same things.
Each ObjectName is paired with an unique integer. Then I create a
Map<ObjectName, Integer> objectPorts = new HashMap<>();
I add to this map two nodes with a duplicate string in their serviceList
example:
objectName1's serviceList has {method1, method2, method3}, while objectName2's serviceList has {method4, method2, method5}
objectPorts contains two times the string "method2"
Now I want to search the map for "method2" and execute the code of method2. I want the execution of the code to be done only once, not for each entry of "method2".
how to do this?
I was using this code: (edit: added the switch portion for clarification)
public long executeMethod(String methodName, int n1, int n2) throws Exception {
long result = 0;
for(Map.Entry<Object, Integer> pair : something.entrySet()) {
List<String> methods = pair.getkey().serviceList;
if(methods.contains(methodName) {
switch(methodName) {
case "method1":
result = arithmeticClient.method1(n1, n2);
break;
case "method2":
result = arithmeticClient.method2(n1, n2);
break;
case "method3":
result = arithmeticClient.method3(n1, n2);
break;
case "method4"
result = arithmeticClient.method4(n1, n2);
break;
}
}
return result;
}
but it executes the code of methodName for each instance of methodName present in the map, so it's not what i want it to do. how can I modify it?
From what I am understanding, all you would need to do is break out of the for loop once it has executed. So something like this --
for(Map.Entry<Object, Integer> pair : something.entrySet()) {
List<String> methods = pair.getkey().serviceList;
if(methods.contains(methodName) {
does something
break;
}
}
break is actually a java keyword that "breaks" out of the current loop you are in. So adding it after the code "does something" would mean the loop would exit and the code would only be executed the one time.
The simple way to fix this would be just to add a boolean to indicate if method 2 had been called previously during the loop:
public long executeMethod(String methodName, int n1, int n2) throws Exception {
long result 0;
boolean executed = false;
for(Map.Entry<Object, Integer> pair : something.entrySet()) {
List<String> methods = pair.getkey().serviceList;
if(methods.contains(methodName) && !executed){
//do something
executed = true;
}
}
return result;
}
This will stop method 2 or whatever from being executed more than one time if the value is contained in multiple Lists associated with the objects of your map.

Java - Increase the value of an int size method by 1 everytime the method is called

I'm stuck on this one question I can't get my head around. I need to write a method to increase the number of "votes" of a specific "act" by one and then print out the updated vote count for that specific act. I'm working with ArrayLists here as well to point out.
Here is the logic you want to follow:
1: Iterate through ArrayList of 'acts'
2: Check for specified 'act'
3: If 'act' equals specified 'act', add one to your counter variable (votes++)
This is as much information as I'll give out without code to show what you've tried!
You could use a Map:
Class VoteCounter {
Map<Integer, Integer> actToCounterMap = new HashMap<Integer, Integer>();
public void raiseVoteForAct(int actId) {
if (actToCounterMap.contains(actId) {
int curVote = actToCounterMap.get(actId);
curVote++;
actToCounterMap.put(actId, curVote);
} else {
// init to 1
actToCounterMap.put(actId, 1);
}
}
}
You can print entire objects out in java, such as
System.out.println("Array list contains: " + arrayListName);
which will print the contents of the array without iterating through each value, although it may have odd syntax. As for the "acts", which I assume you mean objects, if you want to iterate the number of votes by one, you can have a class like this:
public class Act{
int votes = 0;
public void increaseVote(){
votes ++;
//You can also do votes = votes + 1, or votes += 1, but this is the fastest.
}
//While were at it, let's add a print method!
pubic void printValue(){
System.out.println("Votes for class " + this.getClass().getName() + " = " + votes + ".");
}
}
Finally, for a class with the arrayList:
class classWithTheArrayList {
private ArrayList<Act> list = new ArrayList<Act>();
public static void main(String[] args){
Act example1 = new Act();
list.add(example1);
//ArrayLists store a value but can't be changed
//when in the arraylist, so, after updating the value like this:
Act example2 = new Act();
example2.increaseVote();
//we need to replace the object with the updated one
replaceObject(example1, example2);
}
public void replaceObject(Object objToBeRemoved, Object objToReplaceWith){
list.add(objToReplaceWith, list.indexOf(objToBeRemoved); //Add object to the same position old object is at
list.remove(objToBeRemoved); //Remove old object
}
}
A slightly more efficient vote counter.
class VoteCounter<T> {
final Map<T, AtomicInteger> actToCounterMap = new HashMap<>();
public void raiseVoteForAct(T id) {
AtomicInteger ai = actToCounterMap.get(id);
if (ai == null)
actToCounterMap.put(id, ai = new AtmoicInteger());
ai.incrementAndGet();
}
}
Instead of AtomicInteger you can use new int[1] but it's relatively ugly. ;)

Iterating through hashmap and creating unique objects - trying to prevent duplicates

I explain what I am trying to do in comments above the parts in the method:
public int addPatron(String name) throws PatronException {
int i = 0;
//1. Iterate through a hashmap, and confirm the new name I am trying to add to the record doesn't already exist in the hashmap
for (Map.Entry<Integer, Patron> entry : patrons.entrySet()) {
Patron nameTest = entry.getValue();
//2. If the name I am trying to add already exists, we want to throw an exception saying as much.
if (nameTest.getName() == name) {
throw new PatronException ("This patron already exists");
//3. If the name is unique, we want to get the largest key value (customer number) already in the hash, an increment by one.
} else if (nameTest.getName() != name) {
Map.Entry<Integer,Patron> maxEntry = null;
for(Map.Entry<Integer, Patron> entryCheck : patrons.entrySet()) {
if (maxEntry == null || entryCheck.getKey() > maxEntry.getKey()) {
maxEntry = entryCheck;
i = maxEntry.getKey();
i++;
}
}
} else {
throw new PatronException("Something's not working!");
}
//4. If everything is ok up to this point, we want to us the name and the new customer id number, and use those to create a new Patron object, which then gets added to a hashmap for this class which contains all the patrons.
Patron newPatron = new Patron(name, i);
patrons.put(i, newPatron);
}
return i;
}
When I try and run a simple unit test that will fail if I successfully add the same name for addPatron twice in a row, the test fails.
try {
testLibrary.addPatron("Dude");
testLibrary.addPatron("Dude");
fail("This shouldn't have worked");
The test fails, telling me the addPatron method is able to use the same name twice.
#Jon Skeet:
My Patron class looks like this:
public class Patron {
//attributes
private String name = null;
private int cardNumber = 0;
//operations
public Patron (String name, int cardNumber){
this.name = name;
this.cardNumber = cardNumber;
}
public String getName(){
return name;
}
public int getCardNumber(){
return cardNumber;
}
}
As others have said, the use of == for comparing strings is almost certainly inappropriate. However, it shouldn't actually have caused a problem in your test case, as you're using the same constant string twice, so == should have worked. Of course, you should still fix the code to use equals.
It's also not clear what the Patron constructor or getName methods do - either of those could cause a problem (e.g. if they create a new copy of the string - that would cause your test to fail, but would also be unnecessary usually).
What's slightly more worrying to me is this comment:
// 3. If the name is unique, we want to get the largest key value (customer number)
// already in the hash, an increment by one.
This comment is within the main loop. So by that point we don't know that the name is unique - we only know that it doesn't match the name of the patron in this iteration.
Even more worrying - and I've only just noticed this - you perform the add within the iteration block too. It seems to me that you should have something more like this:
public int addPatron(String name) throws PatronException {
int maxKey = -1;
for (Map.Entry<Integer, Patron> entry : patrons.entrySet()) {
if (entry.getValue().getName().equals(name)) {
// TODO: Consider using IllegalArgumentException
throw new PatronException("This patron already exists");
}
maxKey = Math.max(maxKey, entry.getKey());
}
int newKey = maxKey + 1;
Patron newPatron = new Patron(name, newKey);
patrons.put(newKey, newPatron);
return newKey;
}
Additionally, it sounds like really you want a map from name to patron, possibly as well as the id to patron map.
You need to use equals to compare String objects in java, not ==. So replace:
if (nameTest.getName() == name) {
with:
if (nameTest.getName().equals(name)) {
Try to use
nameTest.getName().equals(name)
instead of
nameTest.getName() == name
because now you're comparing references and not the value of the String.
it's explained here
Took another look on your code
Well i took another look on your code and the problem is, that your HashMap is empty at the start of the Test. So the loop will never be runned ==> there will never bee a Patron added or an Exception thrown.
The cause of the problem is how you have used the compare operator ==.
When you use this operator against two objects, what you test is that variable point to the same reference.
To test two objects for value equality, you should use equals() method or compareTo if available.
For String class, invoke of equals is sufficient the check that the store same characters more.
What is equals method ?
To compare the values of Object
The problem is how you compare names.

Java see if arraylist contains string

I have a class called Paragens like this:
public class Paragens {
static int contadorParagens = 1;
String nomeParagem;
int id;
public Paragens(String nomeParagem) {
this.nomeParagem = nomeParagem;
this.id = contadorParagens++;
}
// getters and setters for nomeParagem
}
Every Paragens object has a name and an Id.
This class has a main method where I create several Paragens objects and store them inside an ArrayList like this:
public static void main(String[] args) {
ArrayList<Paragens> paragens = new ArrayList<Paragens>();
paragens.add(new Paragens("name1");
// ... add more paragens
}
This is working ok. If I insert a bunch of paragens and print them I can see tat is all ok.
What I am trying to do is to ask the user to input a paragem name and then I want to see if that paragem is already in the ArrayList.
String name;
System.out.println("Insert paragem name: ");
pickName = sc.nextLine();
System.out.println(paragens.contains(pickName));
What am I doing wrong?
contains checks to see if the list contains the actual thing you handed it. In this case, you're passing in a String name, but comparing it to Paragem instances. contains can't magically guess that it's supposed to look at a given property on the Paragem instances to compare the string.
You can easily loop the list to find out for yourself:
boolean found = false;
for (Paragem p : paragems) {
if (p.nomeParagem.equals(pickName)) { // Or use an accessor function for `nomeParagem` if appropriate
found = true;
break;
}
}
...or as a function:
boolean containsParagemWithName(ArrayList<Paragem> paragems, String pickName) {
for (Paragem p : paragems) {
if (p.nomeParagem.equals(pickName)) {
return true;
}
}
return false;
}
Well, you need to implement the contains method yourself. Do a for loop over the entire array and check if the name of one of the elements is equal with what you're trying to add. If not, add a new Paragens(pickName).
Objects by default are compared by their memory location. So if you have two Paragem with the same name, they are still not equal.
So either, you check the name of each one:
boolean checkDuplicate(String pickName) {
for (Paragem p : paragems) {
if (p.nomeParagem.equals(pickName)) return true;
}
return false;
}
or implement (override) the equals method to compare names (you should be calling contains on a new Paragem object then instead of a String, though).

Categories