If we want single key for multiple values - java

If we have input file which contains the pair of state and city, there can be multiple cities which belongs to same state. What we have to do is we have to make that single state as key and the cities which belongs to that state as value.
For example, I am reading the following data from a file:
Maharashtra - Pune
Madhyapradesh - Bhopal
Maharashtra - Mumbai
Maharashtra - Nagpur
Here Maharashtra will become a key, with Pune, Mumbai and Nagpur becoming values. What I did is first I split The data into state and city. I am now trying to store the states in a list and then check the list but I am stuck.
How can I make the Maharashtra as key and Pune, Mumbai and Nagpur as its respective values? Like this:
Maharashtra- Pune, Mumbai, Nagpur.
This is what I have so far:
public class DataManagerImpl implements DataManager {
#Override
public Map<String, List<String>> populateCityDataMap(String fileName)
throws FileNotFoundException {
// TODO Auto-generated method stub
Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> valSetOne = new ArrayList<String>();
List<String> list=null;
String nameAndRollNumber=null;
String[] nameAndRollNumbers =null;
String State=null;
Scanner s = null;
try {
s = new Scanner(new File("F:\\Participant_Workspace\\Q4\\CityStateLocator\\StateCityDetails.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (s.hasNext()) {
nameAndRollNumber = s.nextLine();
nameAndRollNumbers = nameAndRollNumber.split("-");
State = nameAndRollNumbers[0];
String City=nameAndRollNumbers[1];
/*System.out.println(valSetOne);
map.put(State,valSetOne);*/
System.out.println(State+" "+City);
list.add(State);
}
/*Iterator<String> CrunchifyIterator = list.iterator();
while (CrunchifyIterator.hasNext()) {
System.out.println(CrunchifyIterator.next());
}*/
System.out.println(list);
return null;
}
}

You need something like map with key as state (which is a String) and value as list of cities (i.e. list of strings). So your data structure should be something like:
Map<String, List<String>> map ...
List<String> cities = map.get(state);
if (cities == null) {
cities = new ArrayList<String>();
map.put(state, cities);
}
cities.add(city);

Related

Input a name and a role and get an output of that role with the names

I need to do this for school. Its supposed to be a JAVA project.
So for example, if we give an input:
thomas teacher
charlie student
abe janitor
jenny teacher
The output will be:
teachers,thomas,jenny
students,charlie,
janitor,abe.
I am just a beginner so, so far I have this code:
`Scanner in = new Scanner(System.in);
String line = in.nextLine();
String[] words = line.split(" ");
//TreeMap treemap = new TreeMap();
ArrayList<String> admin = new ArrayList<String>();
Scanner input = new Scanner(System.in);
while(true){
Boolean s = input.nextLine().equals("Done");
//treemap.put(line, "admin");
if(words[1].contentEquals("admin")){
admin.add(words[0]);
}
else if(s == true){
break;
}
}
System.out.println("admins," + "," + admin);`
I was originally using a treemap but I don't know how to make it work so I thought of using an ArrayList and eliminating the brackets at the end.
EDIT:
So I now have the code:
HashMap<String, String> teacher = new HashMap<String, String>();
HashMap<String, String> student = new HashMap<String, String>();
HashMap<String, String> janitor = new HashMap<String, String>();
System.out.println("Enter a name followed by a role.");
Scanner in = new Scanner(System.in);
String line = in.nextLine();
Scanner name = new Scanner(System.in);
String r = name.nextLine();
while(true){
if(line.equals(r + " " + "teacher")){
teacher.put(r, "teacher");
}
}
I'll give you the hint because you should do it yourself.
Use a HashMap<String, List<String>> map and insert your inputs like below:
if(map.containsKey(words[1]))
{
List<String> list = map.get(words[1]);
list.add(words[0]);
map.put(words[1],list);
}
else
{
map.put(words[1],Arrays.asList(words[0]))
}
This way you will get list of names corresponding to each types(student/teacher) etc.
After that iterate over the map and print the list.
I think for a small amount of occupations it's reasonable to accomplish this using just array lists. I think the part you are having trouble with is the input structure so I'll help you out with an example of how to do that part and let you handle the filtering on your own:
private List<String> teachers = new ArrayList<>();
private List<String> students = new ArrayList<>();
private List<String> janitors = new ArrayList<>();
public void seperatePeople(){
Scanner in = new Scanner(System.in);
while(true){
//Keep getting the next line in an infinite loop
String line = in.nextLine();
if(line.equals("Done")){
break; //end the loop
}else{
//Split on the spaces
String[] personArray = line.split(" ");
//Remember each line is structured like : name, occupation
//So when we split the line the array list we get from it
//will be in the same order
putInArray(personArray[0], personArray[1]);
}
}
//Do whatever printing you have to do down here
}
private void putInArray(String name, String occupation) {
//filter and add to the correct list in here
}
If you wanted to implement this using a hashmap the input method would be the same, but instead of putting names into 3 pre-made occupation arraylists you create arraylists and put them inside a hashmap as you go:
private HashMap<String, List<String>> peopleHashMap = new HashMap<>();
public void seperatePeople(){
Scanner in = new Scanner(System.in);
while(true){
//Keep getting the next line in an infinite loop
String line = in.nextLine();
if(line.equals("Done")){
break; //end the loop
}else{
//Split on the spaces
String[] personArray = line.split(" ");
//Remember each line is structured like : name, occupation
//So when we split the line the array list we get from it
//will be in the same order
putInArray(personArray[0], personArray[1]);
}
}
//You can get all the keys that you created like this
List<String> keys = new ArrayList<>(peopleHashMap.keySet());
}
private void putInArray(String name, String occupation) {
if(peopleHashMap.containsKey(occupation)){
//If the key (occupation in this case) is already in the hashmap, that means that we previously
//made a list for that occupation, so we can just the name to that list
//We pull out a reference to the list
List<String> listOfNames = peopleHashMap.get(occupation);
//And then put the new name into that list
listOfNames.add(name);
}else{
//If the key isn't in the hashmap, then we need to make a new
//list for this occupation we haven't seen yet
List<String> listOfNames = new ArrayList<>();
//We then put the name into the new list we made
listOfNames.add(name);
//And then we put that new list with the into the hashmap with the occupation as the key
peopleHashMap.put(occupation, listOfNames);
}
}

How to retrieve word after specific word in Java?

I've this kind of String:
{aa=bbbb, cc=blabla1, ee=ffff, cc=blabla2, gg=hhhh, cc=blabla3,.......}
and i want to get a list of all words after cc=.
How can i do it? I'm not very confident with regex stuff.
public static void main(String[] args) {
String input = "aa=bbbb, cc=blabla1, ee=ffff, cc=blabla2, gg=hhhh, cc=blabla3";
String[] splitValues = input.split(", ");
Map<String,List<String>> results = new Hashtable<>();
List<String> valueList = null;
// iterate through each key=value adding to the results
for (String a : splitValues) {
// a = "aa=bbbb" etc
String[] keyValues = a.split("=");
// you can check if values exist. This assumes they do.
String key = keyValues[0];
String value = keyValues[1];
// if it is already in map, add to its value list
if (results.containsKey(key)) {
valueList = results.get(key);
valueList.add(value);
} else {
valueList = new ArrayList<>();
valueList.add(value);
results.put(key, valueList);
}
}
System.out.println("cc= values");
valueList = results.get("cc");
// assumes value is in results
for (String a : valueList)
System.out.println(a);
}
Your question is very vague but I am guessing the String is provided as is, like:
String toSearch = "{aa=bbbb, cc=blabla1, ee=ffff, cc=blabla2, gg=hhhh, cc=blabla3,.......}";
By list I am guessing you are referring to the abstract List object and not to an array. Here is a solution:
String toSearch = "{aa=bbbb, cc=blabla1, ee=ffff, cc=blabla2, gg=hhhh, cc=blabla3,.......}";
List<String> result = new ArrayList<String>();
int prevMatch = 0;
while (toSearch.indexOf("cc=", prevMatch+1) != -1) {
result.add(toSearch.substring( // Substring method.
toSearch.indexOf("cc=",prevMatch+1)+3,toSearch.indexOf(",") //Getting correct indexes.
));
prevMatch = toSearch.indexOf("cc=",prevMatch+1);
}
The prevMatch variable ensures that the indexOf("cc=") that will be returned will be the next one occurring in the String. For the above String the returning ArrayList will contain the words "blabla1","blabla2", "blabla3" and whatever else is encountered.

Receiving "null" in Place of Correct Values

I'm currently using Jersey REST to create a webpage that has a list of birds and taxonomy number, with a link to a page specifically about the bird in question. While my links work between the two pages, and my Bird Name and Taxonomy Number appear, I can't get the order or family name to appear. Following is the code in question.
#Path("/birdslist")
public class BirdsList extends Birds {
#GET
#Path("/all")
#Produces("text/html")
public String all() {
Iterator iterator = birdnames.keySet().iterator();
String page = "<html><title>All Birds</title><body>";
page += "<p>This is the list of all birds. <br> Click the taxonomy number of the bird you wish to view in detail.</p>";
while(iterator.hasNext()){
Object key = iterator.next();
String value = birdnames.get(key);
HashSet fam = family.get(key);
HashSet ord = order.get(key);
}
for (String key : birdnames.keySet()) {
page += String.format("<p>Name:%s <br> Taxonomy Number:<a href=%s>%s</a></p>",birdnames.get(key),key,
key);
getBird(key);
}
page += "</body></html>";
return page;
}
#GET
#Path("{key}")
#Produces("text/html")
public String getBird(#PathParam("key") String key) {
String page = "<html><title>Bird #: {key}</title><body>";
page += String.format("<p>This page contains info on the %s</p>",birdnames.get(key));
page += String.format("<p>Name:%s <br> Taxonomy Number:%s <br> Family:%s <br> Order:%s</p>",birdnames.get(key),key,family.get(key),order.get(key));
page += "<p>Please click <a href=all>here</a> to return to the list of all birds.</p>";
page += "</body></html>";
return page;
}
}
The family and order are saved in a HashSet that is inside of a hashmap, while bird name is in a hashmap. It was written over from a csv file and converted into hashmaps. Following is that code.
public class Birds {
HashMap<String,String> birdnames;
HashMap<String,HashSet<String>> family;
HashMap<String,HashSet<String>> order;
/**
Constructor reads the CSV of all birds
*/
public Birds() {
// long path to eBirds assuming Maven "mvn exec:java" is many levels up
String fileName = "src/main/java/com/example/rest/eBirds.csv";
boolean firstLine = true;
this.birdnames = new HashMap<String,String>();
this.family = new HashMap<String,HashSet<String>>();
this.order = new HashMap<String,HashSet<String>>();
try {
BufferedReader R = new BufferedReader(new FileReader(fileName));
String line;
while (true) {
line = R.readLine();
if (line == null) break;
if (firstLine) { // ignore the first line, it's not a bird
firstLine = false;
continue;
}
String[] fields = line.split(",");
if (!fields[1].equalsIgnoreCase("species")) continue; // ignore all but species records
birdnames.put(fields[0],fields[4]); // add this bird to name table
// extract the order name from fields[6]
String ordername = fields[6];
if (!order.containsKey(ordername)) { // if needed, create first-time order set
order.put(ordername,new HashSet<String>());
}
order.get(ordername).add(fields[0]); // new order member by number for lookup
// extract the family name from fields[7] -- removing quotes first if needed
String famname = fields[7].replace("\"","");
if (!family.containsKey(famname)) { // if needed, create first-time family set
family.put(famname,new HashSet<String>());
}
family.get(famname).add(fields[0]); // new family member by number for lookup
}
}
catch (IOException e) { System.out.println("Stack trace: " + e); }
}
...
}
I've never used HashSets before, that was part of the given info to us. Our assignment was to create a list page and pages specific to each bird and link between the two. I just can't get these last two values to appear correctly. Can anyone help?
Here you use the same key for all values, birdnames, family and order:
while(iterator.hasNext()){
Object key = iterator.next();
String value = birdnames.get(key);
HashSet fam = family.get(key);
HashSet ord = order.get(key);
}
But you initialize them with different keys:
// extract the order name from fields[6]
String ordername = fields[6];
if (!order.containsKey(ordername))
{ // if needed, create first-time order set
order.put(ordername, new HashSet<>());
}
order.get(ordername).add(fields[0]); // new order member by number for lookup
Here the key would be fields[6] and not the birdnames key.
If you want to keep using the same key, you could do the following for the orders:
if (!order.containsKey(fields[0]))
{
order.put(fields[0], new HashSet<>());
}
order.get(fields[0]).add(fields[6]);
Then you can use:
HashSet ord = order.get(key);
And you will receive all the orders for that bird name.
If you don't want to change that and still use the same key you could do something like the following, but that is highly discouraged as it destroys the purpose of using a map in the first place:
Set<String> ord = new HashSet<>();
for (String tmp : order.keySet())
{
if (order.get(tmp).contains(key))
ord.add(tmp);
}
Here ord would contain all the orders for the "key".
As you can see, you need to do much more redundant work, if you don't switch value and "key".

Compare two arraylists to return the latest date

I have two arraylists as follows.
ArrayList<String> keys = new ArrayList<>();
ArrayList<String> values = new ArrayList<>();
keys.add("1","1","1","2","2","3");
values.add("2016-06-22 07:18:45", "2016-06-22 08:18:45", "2016-06-22 09:18:45",
"2016-06-22 03:18:45","2016-06-22 04:18:45","2016-06-22 01:18:45");
Now i need the function
HashMap latestValues(keys, values);
The output should be as follows,
["1"=>"2016-06-22 09:18:45","2"=>"2016-06-22 04:18:45", "3"=>"2016-06-22 01:18:45"]
Returning the latest dated single value for that particular key. Can anyone please suggest how to achieve this.
Thanks and advance!
I think this will do it.
public static void main(String[] args) {
ArrayList<String> keys = new ArrayList<>(Arrays.asList("1", "1", "1", "2", "2", "3"));
ArrayList<String> values = new ArrayList<>(Arrays.asList("2016-06-22 07:18:45", "2016-06-22 08:18:45", "2016-06-22 09:18:45",
"2016-06-22 03:18:45", "2016-06-22 04:18:45", "2016-06-22 01:18:45"));
HashMap<String, String> map = new HashMap<String, String>();
for (int i = 0; keys.size() == values.size() && i < keys.size(); i++) {
String key = keys.get(i);
String value = values.get(i);
if (!map.containsKey(key) || dateAsNo(value) > dateAsNo(map.get(key))) {
map.put(key, value);
}
}
System.out.println(map);
}
public static long dateAsNo(String v) {
return Long.parseLong(v.replaceAll("\\D", ""));
}
It will only work if all the dates have the same format yyyy-MM-dd hh:mm:ss
You can use the following approach. Values will be overwritten only when date is newer (I am assuming you are not changing the date format)
Map<String,String> hashMap = new HashMap<>();
List<String> keys = new ArrayList<>();
List<String> values = new ArrayList<>();
if(keys.size() != values.size())
return null;
for(int i=0; i<keys.size(); i++){
String keyVal = hashMap.get(keys.get(i));
if(keyVal==null || keyVal.compareTo(values.get(i))>0){
// second condition ensures value is only replaced if it is a later date
hashMap.put(keys.get(i), values.get(i));
}
}
return hashMap;
Try the same thing that you would do if you wre doing this manually. set your current key and go through your list till you find different key and put the current key and appropriate value (that is the value with the same index) in your map
public static void main (String [] args) throws IOException{
ArrayList<String> keys = new ArrayList<>();
ArrayList<String> values = new ArrayList<>();
keys.add("1");keys.add("1"); keys.add("1");
keys.add("2");keys.add("2");
keys.add("3");
values.add("2016-06-22 07:18:45");values.add("2016-06-22 08:18:45");values.add("2016-06-22 09:18:45");
values.add("2016-06-22 03:18:45");values.add("2016-06-22 04:18:45");
values.add("2016-06-22 01:18:45");
Map<String,String> myMap = new HashMap<>();
String currentKey = keys.get(0); // set your current key and go through your list till you find the next key and put the current key and appropriate value (that is the value with the same index) in your map
for(int i = 0;i<keys.size();i++){
if(!currentKey.equalsIgnoreCase(keys.get(i))){
myMap.put(currentKey, values.get(i-1));
currentKey = keys.get(i);
}
if(i==keys.size()-1){
myMap.put(currentKey, values.get(i));
}
}
System.out.println(myMap);
}
you can write just like :
package java7.demo;
import java.util.*;
public class MapTest {
public static void main(String args[]){
ArrayList<String> keys = new ArrayList<>();
ArrayList<String> values = new ArrayList<>();
keys.add("1");
keys.add("1");
keys.add("1");
keys.add("2");
keys.add("2");
keys.add("3");
values.add("2016-06-22 07:18:45");
values.add("2016-06-22 08:18:45");
values.add("2016-06-22 09:18:45");
values.add("2016-06-22 03:18:45");
values.add("2016-06-22 04:18:45");
values.add("2016-06-22 01:18:45");
LinkedHashMap<String,String>map = new LinkedHashMap<String,String>();
for(int i =0; i<keys.size();i++){
map.put(keys.get(i),values.get(i));
}
System.out.println(map);
}
}
as Map(include hashmap,linkedhashmap)replace old key value with new key value if old key value and new key value has same value,you will get 1->2016-06-22 09:18:45.at first it will put[ 1,2016-06-22 07:18:45]to map,in second loop,it will replace with [1,2016-06-22 08:18:45].int third time loop,it will replace with [1,09:18:45].to get data according to insertion Order,I use LinkedHashMap.

How to Iterate over too big ArrayList<String>?

I have two ArrayList sourceMessageList and TargetMessageList. I need to compare both the message list data.
Now lets say List1 - 100 Records. List2 - 1000 records
From List1- 1st record is compared with each record in list2 and then List1- 2nd record is compared with each record in list2.
But list2 is getting the value hasNext() to true for 1st source data in list1.
private void compareMessageList(ArrayList<String> source_messageList, ArrayList<String> target_messageList)
throws Exception {
// TODO Auto-generated method stub
Iterator<String> sourceMessageIterator = source_messageList.iterator();
Iterator<String> targetMessageIterator = null;
while (sourceMessageIterator.hasNext()) {
String sourceMessage = (String) sourceMessageIterator.next();
targetMessageIterator = target_messageList.iterator();
while (targetMessageIterator.hasNext()) {
String targetMessage = (String) targetMessageIterator.next();
if (getCorpValue(sourceMessage).equalsIgnoreCase(getCorpValue(targetMessage))) {
assertXMLEquals(convertSwiftMessageToXML(sourceMessage), convertSwiftMessageToXML(targetMessage));
}
}
}
if (buffer.toString().length() > 0) {
writeDifferenceTofile(buffer.toString());
buffer.delete(0, buffer.length());
throw new CatsException("There are some differences in the files.");
}
System.out.println("Exiting now ...");
}
The above code is taking too much time to execute.
To speed things up:
HashMap<String, String> lowers = new HashMap<String, String>();
for (String source : source_messageList) {
lowers.put(getCorpValue(source).toLowerCase(), source);
}
for (String target : target_messageList) {
final String corpTarget = getCorpValue(target).toLowerCase();
if(lowers.containsKey(corpTarget)) {
assertXMLEquals(
convertSwiftMessageToXML(lowers.get(corpTarget)),
convertSwiftMessageToXML(target)
);
}
}

Categories

Resources