Here's my first Java class, which includes the TreeMap that I want to loop through:
package myFunctions;
import java.util.TreeMap;
public class myUrls {
public void main() {
TreeMap<String, String> getUrl = new TreeMap<String, String>();
getUrl.put("app1", "URL 1");
getUrl.put("app2", "URL 2");
}
// Print keys and values
for (String i : getUrl.keySet()) {
System.out.println("app name: " + i + " url: " + getUrl.get(i));
}
}
}
Here's my second class, where I want to take the previously mentioned TreeMap and loop through it:
package myFunctions;
public anotherClass() {
DA_devurl myUrls = new DA_devurl();
//Loop through the array and perform seperate actions for each keyvalue pair
}
In your first class, I recommend making your TreeMap a private instance variable with a getter method:
package functions;
import java.util.TreeMap;
public class MyUrls {
private TreeMap<String, String> getUrl;
public MyUrls() {
getUrl = new TreeMap<String, String>();
}
public void main() {
getUrl.put("app1", "URL 1");
getUrl.put("app2", "URL 2");
}
public TreeMap<String, String> getGetUrl() {
return this.getUrl;
}
}
Now, in your second class, all you need to do is call the getter method after creating an instance of your previous class, and then looping through its entries with the proper syntax:
package functions;
import java.util.TreeMap;
import java.util.Map;
public class AnotherClass {
public static void main(String args[]) {
MyUrls myUrl = new MyUrls();
// populates the TreeMap
myUrl.main();
TreeMap<String, String> urls = myUrl.getGetUrls();
// Loop through the array and perform seperate actions for each keyvalue pair
for (Map.Entry<String, String> entry : urls.entrySet()) {
// do something with entry.getKey() and entry.getValue()
}
}
}
Related
Is there a way to sort the Properties object in java?
I have the string which groups the Properties and checks whether the data is available in the map format.
You can find an example without sub-classing Properties and working with Java 8/9/10
By this way, keySet, keys and entrySet methods from Properties return sorted keys. Then method store save the properties file sorted too.
This code is
here
Properties properties = new Properties() {
private static final long serialVersionUID = 1L;
#Override
public Set<Object> keySet() {
return Collections.unmodifiableSet(new TreeSet<Object>(super.keySet()));
}
#Override
public Set<Map.Entry<Object, Object>> entrySet() {
Set<Map.Entry<Object, Object>> set1 = super.entrySet();
Set<Map.Entry<Object, Object>> set2 = new LinkedHashSet<Map.Entry<Object, Object>>(set1.size());
Iterator<Map.Entry<Object, Object>> iterator = set1.stream().sorted(new Comparator<Map.Entry<Object, Object>>() {
#Override
public int compare(java.util.Map.Entry<Object, Object> o1, java.util.Map.Entry<Object, Object> o2) {
return o1.getKey().toString().compareTo(o2.getKey().toString());
}
}).iterator();
while (iterator.hasNext())
set2.add(iterator.next());
return set2;
}
#Override
public synchronized Enumeration<Object> keys() {
return Collections.enumeration(new TreeSet<Object>(super.keySet()));
}
};
Please use this example :
from the link : http://www.java2s.com/Tutorial/Java/0140__Collections/SortPropertieswhensaving.htm
import java.io.FileOutputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Properties;
import java.util.Vector;
public class Main{
public static void main(String[] args) throws Exception {
SortedProperties sp = new SortedProperties();
sp.put("B", "value B");
sp.put("C", "value C");
sp.put("A", "value A");
sp.put("D", "value D");
FileOutputStream fos = new FileOutputStream("sp.props");
sp.store(fos, "sorted props");
}
}
class SortedProperties extends Properties {
public Enumeration keys() {
Enumeration keysEnum = super.keys();
Vector<String> keyList = new Vector<String>();
while(keysEnum.hasMoreElements()){
keyList.add((String)keysEnum.nextElement());
}
Collections.sort(keyList);
return keyList.elements();
}
}
Consider that TreeMap is a sorted Map, then you can do:
//properties as they are:
System.out.println(System.getProperties());
//now sorted:
TreeMap<Object, Object> sorted = new TreeMap<>(System.getProperties());
System.out.println(sorted);
I have a list of a map of strings:
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
This gets populated with the following:
Map<String, String> action1 = new LinkedHashMap<>();
map.put("name", "CreateFirstName");
map.put("nextAction", "CreateLastName");
Map<String, String> action2 = new LinkedHashMap<>();
map.put("name", "CreateAddress");
map.put("nextAction", "CreateEmail");
Map<String, String> action3 = new LinkedHashMap<>();
map.put("name", "CreateLastName");
map.put("nextAction", "CreateAddress");
Map<String, String> action4 = new LinkedHashMap<>();
map.put("name", "CreateEmail");
list.add(action1);
list.add(action2);
list.add(action3);
list.add(action4);
action4 doesn't have a nextAction because it is the last action, but might be easier to just give it a nextAction that is a placeholder for no next action?
Question: How can I sort my list, so that the actions are in order?
ie: the nextAction of an action, is the same as the name of the next action in the list.
Although this seems to be a case of the XY-Problem, and this list of maps is certainly not a "nicely designed data model", and there is likely a representation that is "better" in many ways (although nobody can give recommendations about what the "best" model could be, as long as the overall goal is not known), this is the task that you have at hand, and here is how it could be solved:
First of all, you have to determine the first element of the sorted list. This is exactly the map that has a "name" entry that does not appear as the "nextAction" entry of any other map.
After you have this first map, you can add it to the (sorted) list. Then, determining the next element boils down to finding the map whose "name" is the same as the "nextAction" of the previous map. To quickly find these successors, you can build a map that maps each "name" entry to the map itself.
Here is a basic implementation of this sorting approach:
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class SortListWithMaps
{
public static void main(String[] args)
{
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Map<String, String> action1 = new LinkedHashMap<>();
action1.put("name", "CreateFirstName");
action1.put("nextAction", "CreateLastName");
Map<String, String> action2 = new LinkedHashMap<>();
action2.put("name", "CreateAddress");
action2.put("nextAction", "CreateEmail");
Map<String, String> action3 = new LinkedHashMap<>();
action3.put("name", "CreateLastName");
action3.put("nextAction", "CreateAddress");
Map<String, String> action4 = new LinkedHashMap<>();
action4.put("name", "CreateEmail");
list.add(action1);
list.add(action2);
list.add(action3);
list.add(action4);
// Make it a bit more interesting...
Collections.shuffle(list);
System.out.println("Before sorting");
for (Map<String, String> map : list)
{
System.out.println(map);
}
List<Map<String, String>> sortedList = sort(list);
System.out.println("After sorting");
for (Map<String, String> map : sortedList)
{
System.out.println(map);
}
}
private static List<Map<String, String>> sort(
List<Map<String, String>> list)
{
// Compute a map from "name" to the actual map
Map<String, Map<String, String>> nameToMap =
new LinkedHashMap<String, Map<String,String>>();
for (Map<String, String> map : list)
{
String name = map.get("name");
nameToMap.put(name, map);
}
// Determine the first element for the sorted list. For that,
// create the set of all names, and remove all of them that
// appear as the "nextAction" of another entry
Set<String> names =
new LinkedHashSet<String>(nameToMap.keySet());
for (Map<String, String> map : list)
{
String nextAction = map.get("nextAction");
names.remove(nextAction);
}
if (names.size() != 1)
{
System.out.println("Multiple possible first elements: " + names);
return null;
}
// Insert the elements, in sorted order, into the result list
List<Map<String, String>> result =
new ArrayList<Map<String, String>>();
String currentName = names.iterator().next();
while (currentName != null)
{
Map<String, String> element = nameToMap.get(currentName);
result.add(element);
currentName = element.get("nextAction");
}
return result;
}
}
Instead of using a Map to store the properties of an action (the name and the nextAction), create your own type that's composed of those properties:
class Action {
private String name;
//nextAction
public void perform() {
//do current action
//use nextAction to perform the next action
}
}
The nextAction can now be a reference to the next action:
abstract class Action implements Action {
private String name;
private Action nextAction;
public Action(String name) {
this.name = name;
}
public final void perform() {
perform(name);
nextAction.perform();
}
protected abstract void perform(String name);
}
You can now create your actions by subtyping the Action class:
class CreateFirstName extends Action {
public CreateFirstName(Action nextAction) {
super("CreateFirstName", nextAction);
}
protected final void perform(String name) {
System.out.println("Performing " + name);
}
}
And chain them together:
Action action = new CreateFirstName(new CreateLastName(new CreateEmail(...)));
The nested expressions can get pretty messy, but we'll get to that later. There's a bigger problem here.
action4 doesn't have a nextAction because it is the last action, but might be easier to just give it a nextAction that is a placeholder for no next action
The same problem applies to the code above.
Right now, every action must have a next action, due to the constructor Action(String, Action). We could take the easy route and pass in a placeholder for no next action (null being the easiest route):
class End extends Action {
public End() {
super("", null);
}
}
And do a null check:
//class Action
public void perform() {
perform(name);
if(nextAction != null) {
nextAction.perform(); //performs next action
}
}
But this would be a code smell. You can stop reading here and use the simple fix, or continue below for the more involved (and educational) route.
There's a good chance that when you do use null, you're falling victim to a code smell. Although it doesn't apply to all cases (due to Java's poor null safety), you should try to avoid null if possible. Instead, rethink your design as in this example. If all else fails, use Optional.
The last action is not the same as the other actions. It can still perform like the other, but it has different property requirements.
This means they could both share the same behavior abstraction, but must differ when it comes to defining properties:
interface Action {
void perform();
}
abstract class ContinuousAction implements Action {
private String name;
private Action nextAction;
public ContinuousAction(String name) {
this.name = name;
}
public final void perform() {
perform(name);
nextAction.perform();
}
protected abstract void perform(String name);
}
abstract class PlainAction implements Action {
private String name;
public PlainAction(String name) {
this.name = name;
}
public final void perform() {
perform(name);
}
protected abstract void perform(String name);
}
The last action would extend PlainAction, while the others would extend ContinuousAction.
Lastly, to prevent long chains:
new First(new Second(new Third(new Fourth(new Fifth(new Sixth(new Seventh(new Eighth(new Ninth(new Tenth())))))))))
You could specify the next action within each concrete action:
class CreateFirstName extends ContinuousAction {
public CreateFirstName() {
super("CreateFirstName", new CreateLastName());
}
//...
}
class CreateLastName extends ContinuousAction {
public CreateLastName() {
super("CreateLastName", new CreateEmail());
}
//...
}
class CreateEmail extends PlainAction {
public CreateEmail() {
super("CreateEmail");
}
//...
}
The ContinuousAction and PlainAction can be abstracted further. They are both named actions (they have names), and that property affects their contract in the samw way (passing it to the template method process(String)):
abstract class NamedAction implements Action {
private String name;
public NamedAction(String name) {
this.name = name;
}
public final void perform() {
perform(name);
}
protected abstract void perform(String name);
}
//class ContinuousAction extends NamedAction
//class PlainAction extends NamedAction
i have some keys which are pointing to many values in a multimap. how can i retrieve the key basing on the value present in the multimap. Here is my code.
package com.manoj;
import java.util.Set;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
public class GuavaMap
{
public static void main(String[] args)
{
Multimap regions = ArrayListMultimap.create();
regions.put("asia", "afganistan");
regions.put("asia", "bangladesh");
regions.put("asia", "inida");
regions.put("asia", "japan");
regions.put("asia", "burma");
regions.put("europe", "andorra");
regions.put("europe", "austria");
regions.put("europe", "belgium");
regions.put("europe", "cyprus");
regions.put("oceania","australia");
regions.put("oceania", "fiji");
regions.put("oceania", "nauru");
Set<String> keys = regions.keySet();
System.out.println("key\t\t\t"+"values\t\t\t");
System.out.println();
String comp = null;
for(String key : keys)
{
System.out.print(key);
System.out.println(regions.get(key));
}
}
}
the above code is providing me the output as follows
i need the region name basing on the country.
Example: if i give "australia" output should be "oceania"
you can invert it
Multimap<String, String> invregions = Multimaps.invertFrom(regions , ArrayListMultimap.<String, String>create());
and call get("yourcountry");
this will give you the keys containing your country
Firstly, I would like to suggest to not use raw types and explicitly mention Key and Value type while creating Map.
Regarding your question to retrieve key depending on value, you can iterate over all entries of the map to do the same like:
class GuavaMap
{
//Explicitly mentioned key and value both are Strings here
public static Multimap<String, String> regions = ArrayListMultimap.<String, String>create();
public static void main(String[] args)
{
regions.put("asia", "afganistan");
regions.put("asia", "bangladesh");
regions.put("asia", "inida");
regions.put("asia", "japan");
regions.put("asia", "burma");
regions.put("europe", "andorra");
regions.put("europe", "austria");
regions.put("europe", "belgium");
regions.put("europe", "cyprus");
regions.put("oceania","australia");
regions.put("oceania", "fiji");
regions.put("oceania", "nauru");
Set<String> keys = regions.keySet();
System.out.println("key\t\t\t"+"values\t\t\t");
System.out.println();
String comp = null;
for(String key : keys)
{
System.out.print(key);
System.out.println(regions.get(key));
}
//usage of below defined method
String region = getRegion("australia");
System.out.println("Region for australia:" + region);
}
// Function to get the region name i.e. key
public static String getRegion(String country){
for(Entry<String, String> entry : regions.entries()){
if(entry.getValue().equals(country))
return entry.getKey();
}
return "Not found";
}
}
Thanks for the reply.
i found a solution based on the list, map and hashmap
package com.manoj;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
public class NestedList
{
public static void main(String[] args)
{
List asia = Arrays.asList("afganistan","japan","india","pakistan","singapore","sri lanka");
List europe = Arrays.asList("albania","belarus","iceland","russia","norway","turkey");
List middleEast = Arrays.asList("australia","new zealand","samoa","tonga","vanuatu");
Map region = new HashMap<>();
region.put("asia",asia);
region.put("europe", europe);
region.put("middleeast" ,middleEast);
String reg = null;
String val = null;
for(Object key : region.keySet())
{
reg = key.toString();
Iterator it = ((List) region.get(key)).iterator();
while(it.hasNext())
{
val = it.next().toString();
if(val.equalsIgnoreCase("india"))//here you have to provide the country name
{
System.out.println(reg);
}
}
}
}
}
I really do not understand why I am getting this compile error after the parentheses for "Map<String, Integer> buildTable(){".
Here is the code I am working on: I already have the city class defined.
import java.util.Map;
import java.util.HashMap;
public class CityMap{
public static void main(String[] args){
String _city;
Map<String, Integer> cityTable = buildTable();
Map<String, Integer> buildTable(){
String aCity;
Map<String, Command> result = new HashMap<String, Command>();
aCity = new City();
result.put("NYC", 100000);
aCity = new City();
result.put("Boston", 500);
return result;
}
I am a beginner, so any explanation is welcome.
You cannot declare methods inside of other methods.
Move your buildTable method outside of the main method (and then you have to either make it static or create an object instance to call it from main).
Your method declaration for buildTable needs to live outside of your method declaration for main.
I.E.,
import java.util.Map;
import java.util.HashMap;
public class CityMap{
public static void main(String[] args)
{
String _city;
Map<String, Integer> cityTable = buildTable();
}
public static Map<String, Integer> buildTable(){
String aCity;
Map<String, Command> result = new HashMap<String, Command>();
aCity = new City();
result.put("NYC", 100000);
aCity = new City();
result.put("Boston", 500);
return result;
}
}
import java.util.Map;
import java.util.HashMap;
public class CityMap {
static Map < String, Integer > buildTable() {
Map < String, Integer > result = new HashMap < String, Integer > ();
result.put("NYC", 100000);
result.put("Boston", 500);
return result;
}
public static void main(String[] args) {
Map < String, Integer > cityTable = buildTable();
}
}
Command is not defined, creating instance variables not to use them will do nothing at all, method can not be declared inside method; only inside class - you can declare class inside method (inner class) and method inside that class.
public static void main(String[] args){} is a method, after all. For this reason you cannot declare another method inside it.
Also, your compiler gets confused when you return result because although it is intended for your buildTable() method, it is placed inside your main() method.
Solution:
public static void main(String[] args){
String _city;
Map<String, Integer> cityTable = buildTable();
}
Map<String, Integer> buildTable(){
String aCity;
Map<String, Command> result = new HashMap<String, Command>();
aCity = new City();
result.put("NYC", 100000);
aCity = new City();
result.put("Boston", 500);
return result;
}
This question already has answers here:
Printing HashMap In Java
(17 answers)
Closed 8 years ago.
I'm trying to learn how hashmaps work and I've been fiddling with a small phonebook program.
But I'm stumped at what to do when I want to print out all the keys.
here's my code:
import java.util.HashMap;
import java.util.*;
public class MapTester
{
private HashMap<String, String> phoneBook;
public MapTester(){
phoneBook = new HashMap<String, String>();
}
public void enterNumber(String name, String number){
phoneBook.put(name, number);
}
public void printAll(){
//This is where I want to print all. I've been trying with iterator and foreach, but I can't get em to work
}
public void lookUpNumber(String name){
System.out.println(phoneBook.get(name));
}
}
Here we go:
System.out.println(phoneBook.keySet());
This will printout the set of keys in your Map using Set.toString() method. for example :
["a","b"]
You need to get the keySet from your hashMap and iterate it using e.g. a foreach loop. This way you're getting the keys which can then be used to get the values out of the map.
import java.util.*;
public class MapTester
{
private HashMap<String, String> phoneBook;
public MapTester()
{
phoneBook = new HashMap<String, String>();
}
public void enterNumber(String name, String number)
{
phoneBook.put(name, number);
}
public void printAll()
{
for (String variableName : phoneBook.keySet())
{
String variableKey = variableName;
String variableValue = phoneBook.get(variableName);
System.out.println("Name: " + variableKey);
System.out.println("Number: " + variableValue);
}
}
public void lookUpNumber(String name)
{
System.out.println(phoneBook.get(name));
}
public static void main(String[] args)
{
MapTester tester = new MapTester();
tester.enterNumber("A name", "A number");
tester.enterNumber("Another name", "Another number");
tester.printAll();
}
}
Maps have a method called KeySet with all the keys.
Set<K> keySet();