Iterating in HashMap of arraylists - java

Briefly - I try to write a method that should convert the values of String[] sourceAllPeopleInMyFamily to single objects of Person.
Then, check if this Person instance exists in HashMap<String, ArrayList<Person>> allPeople. If it does, I should add this Person instance to HashSet<Person> allPeopleInMyFamily.
Person class contains String personName + int personAge.
HashMap<String, ArrayList<Person>> contains the key String personName + the value array list of Person objects.
I wrote this following code.
Since I use HashMap, I use entry to iterate the all the map.
But since the entry checks all keys&values, this prevents me to have a return statement if the object isn't found.
Please advice is there any better iteration for my case?
boolean addPerson (String[] sourceAllPeopleInMyFamily) {
HashMap<String, ArrayList<Person>> allPeople = pointer to another initialized HashMap in another package;
HashSet<Person> allPeopleInMyFamily = new HashSet<Person>();
for (Map.Entry<String, ArrayList<Person>> entry : allPeople.entrySet()) {
for (String sourcePersonInMyFamily : sourceAllPeopleInMyFamily) {
Person personInMyFamily = new Person (sourcePersonInMyFamily); // Create a new person based on sourceAllPeopleInMyFamily array
if (entry.getValue().contains(personInMyFamily) { // Check if personInMyFamily exists in all people set
if (!allPeopleInMyFamily.add(personInMyFamily))
return false;
// } else { return false; } ???????
}
}
}
}

Related

Update HashMap without adding new entry

My program uses two HashmMap and they have exactly the same number of entries and the same keys.
One (tableMap) is static and never changes. The other one is dynamic (partitionMap), this means that I need to update values.
My algorithm got a problem, because seems to be adding one more entry when it is supposed to be not.
//I have a LinkedList of strings that I want to add to the HashMap partitionMap
LinkedList<String> partition = new LinkedList<String>();
for (TerminalNode terminalNode : ctx.U()) {
partition.add(terminalNode.getText());
}
//for each entry of tableMap
for(Entry<String, LinkedList<String>> entry : tableMap.entrySet())
{
//I retrieve keys and values from tableMap
String key = entry.getKey();
LinkedList<String> attributes = entry.getValue();
//the condition: if my linkedlist is included in the other do...
if(attributes.containsAll(partition))
{
//get the list of values
ArrayList<LinkedList<String>> l = partitionMap.get(key);
//but the first time is always null since I init partitionMap without values
if(l==null)
{
ArrayList<LinkedList<String>> firstLL = new ArrayList<LinkedList<String>>();
firstLL.add(partition);
partitionMap.put(key, firstLL); //BUG HERE! add one more entry instead of just updating values
}
else
{
l.add(partition);
partitionMap.put(key, l);
}
}
}
Does anybody have an idea why this is wrong?

How to implement a HashMap from a string input

I have an array list which holds a bunch of activities inputted by the user, each of them have a title which is inputted by the user. I want the title to be parsed and inputted into a hashmap. Now the user can perform a search, where they can type certain keywords. I need to use a hashmap to check which activity in the array list they are referring too.
The problem i am having is that i know we cant have more than one values assosiated with a particular key. For example if the title for activity one is : football game, i want football to = 1 and game to = 1 (which indicates its related to the first activity) so that when the user types in one of those words it will pull up this activity.
You could potentially use a hash map on a list of strings. Make your key be a unique integer and then store any words associated with that integer in the string list. That way "game" could be associated with "soccer game" or "hockey game". But it depends how you associate your strings with your keys I guess.
Map<From, To> looks like it can only map to single things. That is luckily not true since To can also be a List<To> or a Set<To> or even a Map again.
Using complex types as values has some downsides though. You have to create those sets/lists per entry and handle null values.
roughly like
private Map<String, List<Integer>> activityMap = new HashMap<>();
private void add(String key, Integer value) {
List<Integer> list = activityMap.get(key);
if (list == null) {
// must create and add the list
list = new ArrayList<>();
activityMap.put(key, list);
}
list.add(value);
}
private List<Integer> getAll(String key) {
List<Integer> list = activityMap.get(key);
// simpler to use if there is never null as result.
if (list == null)
list = new ArrayList<>();
return list;
}
private void remove(String key, Integer value) {
List<Integer> list = activityMap.get(key);
if (list == null)
return;
// here should probably be list.remove(Object) - it looks confusing with Integer though
for (Iterator<Integer> iterator = list.iterator(); iterator.hasNext();) {
Integer listValue = iterator.next();
if (listValue.equals(value)) {
iterator.remove();
}
}
}
Guava Multimap is an implementation of such a structure in case libraries are an option.
I am not sure what is really want to put into hashmap, and I just assume it looks like this:
"user1" => "bascketbal = 1, footdball = 2"
"user2" => "football = 3"
"user3" => "pingpong = 1"
If so, you can use Map<String, Map<String, Integer>>, e.g:
Map userActiveData = new HashMap<String, Map<String, Integer>>();
//For each user, maybe in a loop
Map<String, Integer> active = new HashMap<String, Integer>();
active.put("football", 1);
active.put("game", 2);
userActiveData.put("user1", active);
Use a list as the value of the HashMap.
Map<String, List<String>> map = new HashMap<String, List<String>>();
Pseudo code:
Parse your title and find the keywords.
If the keyword is a new one Then
add it to the HashMap as a key, and add the Activity_id as the first element of the list.
Else (keyword is already in the HashMap) Then
add Activity_id as the next element of the corresponding list.
When you search a keyword you can return the list with all the Activity_ids that matches the keyword
Example:
Input: 1 - soccer game | 2 - badminton game
This is what HashMap will look like
~KEY~ | ~VALUES(List)~
soccer | 1
badminton | 2
game | 1,2
I think this is what you want, it supports the whole key and a only part of the activity to search, please check the output :
public class ActivityManager {
Map<String, Set<String>> map = new HashMap<String, Set<String>>();
public static void main(String[] args) {
ActivityManager testMap = new ActivityManager();
testMap.addActivity("football game");
testMap.addActivity("basketball game");
Set<String> football=testMap.getActivities("football");
Set<String> basketball=testMap.getActivities("basketball");
Set<String> game=testMap.getActivities("game");
Set<String> footballGame=testMap.getActivities("football game");
System.out.println("-------football------");
printActivities(football);
System.out.println("-------game------");
printActivities(game);
System.out.println("-------basketball------");
printActivities(basketball);
System.out.println("-------football game------");
printActivities(footballGame);
}
public void addActivity(String activity) {
String[] keyWords = activity.split(" ");// split key words, change to what you want if needed
Set<String> activities=null;
for (String key : keyWords) {
activities = map.get(key);
if (activities == null) {// do not have any activities mapped to this key yet
activities = new HashSet<String>();
map.put(key, activities);
}
activities.add(activity);// put new value into it.
}
if (keyWords.length>1){
Set<String> activitiesUsingWholeKey =map.get(activity);//get the activities using the whole word
if(activitiesUsingWholeKey==null){
activitiesUsingWholeKey=new HashSet<String>();
map.put(activity, activitiesUsingWholeKey);
}
activitiesUsingWholeKey.add(activity);
}
}
public Set<String> getActivities(String key){
return this.map.get(key);
}
private static void printActivities(Set<String> activities){
for(String activity:activities)
System.out.println(activity);
}
}
Output :
-------football------
football game
-------game------
basketball game
football game
-------basketball------
basketball game
-------football game------
football game

Android: Find a value inside an Array with a "a like" value

I'm having problem with this part
My Code:
String[] sample = {'name=NAME', 'add=ADD', 'age=AGE', 'gender=GENDER'};
for(int a = 0; a < sample.length; a++) {
if(Arrays.asList(sample).contains("name")) {
Log.d(tag, "successful");
} else {
Log.d(tag, "failed");
}
}
When I'm using this code, it doesn't return true, but when I use .contains("name=NAME")
it returns true.
Is there any possibility to compare a string value using not too specific string?
BTW, those string values came from a file.txt.
If you use Arrays.asList(sample) you will have a list containing the String "name=NAME" hence it doesn't contain the String "name"
You should loop over the array (not needed to create the list)
boolean found = false;
for (String s: sample)
if (s.contains("name"))
found=true;
To get a value based on key:
1) You can use HashMap object
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main(String args[]) {
// create hash map
HashMap newmap = new HashMap();
// populate hash map
newmap.put("name", "abcde");
newmap.put("age", "XX");
newmap.put("Gender", "Male");
// get value of key Gender
String val=(String)newmap.get("Gender");
// check the value
System.out.println("Value for key 3 is: " + val);
}
}
2) You can also use Map object
Map<String, String> map = new HashMap<String, String>();
map.put("name", "abcde");
map.put("age", "XX");
String val=(String)map.get("name");
3) You can also use two dimentional array of string
String data = "name=Name,age=Age";
String[] rows = data.split(",");
String[][] matrix = new String[rows.length][];
int r = 0;
for (String row : rows) {
matrix[r++] = row.split("\\=");
}
System.out.println(matrix[1][1]);
.contains method will check whether the object is present in the ArrayList or not.
Here in your case objects are : "name=NAME","add=ADD","age=AGE", "gender=GENDER" which are of String type. So it is obvious that it returns false.
For you, better practice is to create a class named Person which has attributes like name,add,age and gender. Then store the object of it in ArrayList and you can check whether object is in ArrayList of not using .contains() function. Like below :
class Person{
String name;
String add;
int age;
String gen;
// All getters and setters methods will be here.
}
public static void main(String[] args){
Person p = new Person();
//Here you can set the properties of person using p.setXXX() methods
//Now suppose you have ArrayList of Person object named "per" then you can check
// whether Person exist in it or not using contains like below
per.contains(p) //returns true if per contains object p
//or you can check name by below code
for(Person temp:per){
if(temp.getName().equals(name)){ //returns true if name matchs with Persons name
//do something
}
}

Determining an object's variable name dynamically?

Let's say I have some objects:
ArrayList<SomeObject> list = new ArrayList<SomeObject>();
SomeObject A = new SomeObject();
SomeObject B = new SomeObject();
SomeObject C = new SomeObject();
SomeObject D = new SomeObject();
These constructors automatically add each object to the ArrayList so I can iterate over them but still maintain the variable names for direct access:
public SomeObject(){
// init stuff here
list.add(this);
}
But then, let's say I want to output some debug info, and iterate through list and print out the NAME of each object? How can I do that? Essentially, when "SomeObject A = new SomeObject();" is executed, I want to use reflection (if possible) to determine that this variable's name is "A" (a String) and either store that in the object when the constructor executes, or determine it dynamically through reflection when referencing this object with the variable named "A". Does that make sense? How can I do this?
Thanks!
The compiler doesn't keep the variable names you define in your code, so this isn't possible at run-time.
I don't see why you insist on working with List, as it seems that what you're looking for is a Map. An entry in a map is a named object, e.g. it has a key used to look up the entry in the map.
Map<String,SomeObject> map = new HashMap<String,SomeObject>();
map.put("A",new SomeObject());
map.put("B",new SomeObject());
If your objects have names or need to know their names, then the object should have the name as a property. Using variable names or map keys for object identification is not good.
Map<String,SomeObject> map = new HashMap<String,SomeObject>();
map.put("A",new SomeObject("A"));
map.put("B",new SomeObject("B"));
However, this is repetitive and you may want to refactor that into a more expressive design by introducing new classes:
SomeObjects objects = new SomeObjects();
SomeObject objectA = objects.create("A");
SomeObject objectB = objects.create("B");
// The container can manage references if you like to
SomeObject objectA = objects.get("A");
SomeObjects may use a Map internally to manage the objects:
class SomeObjects {
Map<String,SomeObject> objects = ...;
public SomeObject create(String name) {
SomeObject newObject = new SomeObject(name);
objects.put(name,newObject);
return newObject;
}
public SomeObject get(String name) {
return objects.get(name);
}
}
To iterate over either the object names or over the objects, the container can simply provide iterators for the keys of the map or the values of the map:
public class SomeObjects {
Map<String,SomeObject> objects = ...;
public Iterator<SomeObject> objects() {
return objects.values().iterator();
}
public Iterator<String> names() {
return objects.keySet().iterator();
}
}
To use these iterators, you can do:
public void test() {
SomeObjects objects = ...;
for(SomeObject obj : objects.objects()) {
// Do something with the object
}
for(String objName : objects.names()) {
// Do something with the object name
}
}
If you directly use a Map, you can use the Map's Entry class, which is a key and value pair:
public void test() {
Map<String,SomeObject> objects = new HashMap<String,SomeObject>();
objects.put("A",new SomeObject());
for(Entry entry : objects.entrySet()) {
System.out.printlnt("Processing object with name: " + entry.getKey());
SomeObject obj = entry.getValue();
doSomethingWith(obj);
}
}
you could just create a String field in SomeObject called name and store the name there.
OR
As much as I hate this answer:
Assuming you are creating the same objects every time, you could create a method which checks references, like so:
public void referenceChecker(SomeObject thing){
if( A == thing) System.out.println("A");
else if(B == thing) System.out.println("B");
//etc etc
}
Its not pretty and it's annoying to maintain, but it works

Iterate Hash Map

I have an hashmap declared as
private HashMap testMessages = null;
I will be storing string values in both key and value part of the hashmap retrieved from oracle table.
I am not concerned about the hashmap keys. I want to retrieve the hashmap values alone and check whether string variable filename is prefixed with one of the hash map value and return true if it's same. I want to ensure that hash map values are not null and empty.
function (string filename)
{..
loop thru hashmap values
check whether the variable file name is prefixed with one of the hashmap values if so
return true
otherwise
return false
}
hashmap example:
key1,prod
key2,test
key3,dummy
filename example:
test123_20012010.csv
should return true since the file name is prefixed with one of the hashmap values
How can i do it?
for (String prefix : map.values()) {
if (filename.startsWith(prefix)) {
return true;
}
}
return false;
It should be noted that this is linear time in the number of entries in the map in the worst case. If you have multiple filename that you want to do the check for, it's much better to preprocess the prefixes and build something like a patricia trie and other fast dictionary-like data structures.
Here's a brute force approach to iterate over the hash map values and check whether filename begins with the value.
// generics version
private HashMap<String, String> testMessages = buildMap();
for (String v : testMessages.values()) {
if (filename.startsWith(v) {
// found a map value that starts the file name
}
}
// alternative non-generics version
private HashMap testMessages; // assigned somewhere
for (Object v : testMessages.values()) {
if (filename.startsWith((String) v) {
// found a map value that starts the file name
}
}
leeched from leepoint.net
public static void iterate_over_hashmap(Map mp) {
Iterator it = mp.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
System.out.println(pairs.getKey() + " = " + pairs.getValue());
}
}
You have to treat each entry as a key/value pair and iterate over those as a single entity. Then you cast it into Map.Entry and then you can read both separately
function(String fileName)
{
for(String value : hashMap.values())
{
if(fileName.startsWith(value))
return true;
}
return false;
}

Categories