sorry I am a newbie I have been looking for an example on how I can iterate hashmap and store the entities into MySQL database. the blow code downloads currency rate which I would like to store into my database. the output is
{CCY=USD, RATE=1.5875}
{CCY=EUR, RATE=1.1919}
{CCY=ALL, RATE=166.2959}
{CCY=AMD, RATE=645.4025}
how can I iterate the HashMap and store it into my database? an illustration would be nice or source similar to this scenario.
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
public class Rate {
/** list of string array containing IOSCurrencyCodes*/
final String[] CURRENCY = new String[] { "USD","EUR","ALL","AMD",};
#SuppressWarnings("rawtypes")
void checkRateAllAtEnd() throws Exception {
List<Callable<HashMap>> tasks = new ArrayList<Callable<HashMap>>();
for (final String ccy : CURRENCY) {
tasks.add(new Callable<HashMap>() {
public HashMap<String, Comparable> call() throws Exception {
return getRates(ccy);
}
});
}
ExecutorService executorPool = Executors.newCachedThreadPool();
final List<Future<HashMap>> listRates = executorPool.invokeAll(tasks, 3600, TimeUnit.SECONDS);
for (Future<HashMap> rate : listRates) {
HashMap ccyRate = rate.get();
System.out.println(ccyRate);
}
}
#SuppressWarnings("rawtypes")
public HashMap<String, Comparable> getRates(String ccy) throws Exception {
URL url = new URL("http://finance.yahoo.com/d/quotes.csv?e=.csv&f=sl1d1t1&s=GBP"
+ ccy + "=X");
BufferedReader reader = new BufferedReader(new InputStreamReader(
url.openStream()));
String data = reader.readLine();
String[] dataItems = data.split(",");
Double rate = Double.valueOf(dataItems[1]);
HashMap<String, Comparable> ccyRate = new HashMap<String, Comparable>();
ccyRate.put("CCY", ccy);
ccyRate.put("RATE", rate);
return ccyRate;
}
public static void main(String[] args) {
Rate ccyRate = new Rate();
try {
//ccyConverter.checkRateSequential();
ccyRate.checkRateAllAtEnd();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Map provides entrySet method which is very useful to iterate over a map.
Map#entrySet returns a Set view of the mappings contained in this map. The set is backed by the map, so changes to the map are reflected in the set, and vice-versa. If the map is modified while an iteration over the set is in progress.
ref - link
Code -
HashMap<String, Comparable> ccyRate = new HashMap<String, Comparable>();
for(Map.Entry<String, Comparable> entry: ccyRate.entrySet){
System.out.println(entry.getKey()+" - "+entry.getValue());
}
Related
I want to return a map to my Java code from a stored procedure. The results from PL/SQL in a Map format like Map<key, List>. Is it possible to return data like that?
I have returned the whole data in a string and from java class I have used split logic to split the data and saved them in proper fields. Like an example:
String[] lines = resultString.split(System.lineSeparator()); List<MessageVO> resultPerList = new ArrayList<>();
for (String line : lines) {
MessageVO message = new MessageVO();
String[] fieldArray = line.split(":", 0);
String field= fieldArray[0];
message.setField(field);
resultPerList.add(message);
}
If you like PL/SQL and the resulting lists are small, your solution (structuring data in SQL) is good. In PL/SQL you can take advantage of the listagg statement
Here is functional sample:
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class sasafd {
public static void main(String[] args) {
String resultString = "key1:valuea:valueb:valuec"
+ System.lineSeparator()
+ "key2:valuea:valueb:valuec";
String[] lines = resultString.split(System.lineSeparator());
Map<String, List<String>> resultMap = new HashMap<String, List<String>>();
for (String line : lines) {
String[] fieldArray = line.split(":", 0);
for (String value : fieldArray)
if (resultMap.containsKey(fieldArray[0])) {
resultMap.get(fieldArray[0]).add(value);
} else {
resultMap.put(fieldArray[0], new LinkedList<String>());
}
}
System.out.println(convertWithStream(resultMap));
}
public static String convertWithStream(Map<String, List<String>> map) {
String mapAsString = map.keySet().stream().map(key -> key + "=" + map.get(key))
.collect(Collectors.joining(", ", "{", "}"));
return mapAsString;
}
}
Output:
{key1=[valuea, valueb, valuec], key2=[valuea, valueb, valuec]}
If you like more tabular data, from DB you can use thoughts from this code:
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class sasafd {
public static void main(String[] args) {
String[][] resultSet =
{{"key1","valuea"},{"key1","valueb"},{"key1","valuec"}
,{"key2","valuea"},{"key2","valueb"},{"key2","valuec"}};
Map<String, List<String>> resultMap = new HashMap<String, List<String>>();
for (String[] line : resultSet) {
if (resultMap.containsKey(line[0])) {
resultMap.get(line[0]).add(line[1]);
} else {
resultMap.put(line[0], new LinkedList<String>());
resultMap.get(line[0]).add(line[1]);
}
}
System.out.println(convertWithStream(resultMap));
}
public static String convertWithStream(Map<String, List<String>> map) {
String mapAsString = map.keySet().stream().map(key -> key + "=" + map.get(key))
.collect(Collectors.joining(", ", "{", "}"));
return mapAsString;
}
}
You can also try ORM. If you dislike colon-separated text from PL/SQL you can also use XML, JSON, ...
JDBC doesn't support Map results.
I receive a String with json from an abstract source and I want to reorder the fields in that json so that certain fields come first in specified order and other, uspecified fields can come in any order. Is there a library method that would allow me to do sth like this:
// String reorderFields(String json, String[] orderedFields);
String res = reorderFields("{\"b\":2, \"c\": 3, \"a\":1}", new String[] {"a", "b", "c"});
Assertions.assertEquals("{\"a\":1,\"b\":2,\"c\":3}", res);
Below is solution that should do the trick. It works for first-level fields only. It uses jackson for json handling. Since it operates on basic types only (no custom serializers/deserializers) it should be safe to use for all possible json types.
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ReorderFieldsTest {
public static String reorderFieldsInJson(String json, String[] fields) {
ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> jsonMap;
try {
jsonMap = objectMapper.readValue(json, new TypeReference<Map<String, Object>>() {
});
} catch (Exception e) {
throw new RuntimeException("Error converting json to map", e);
}
Map<String, Object> resMap = new LinkedHashMap<>();
Set<String> orderedFields = new HashSet<>(Arrays.asList(fields));
for (String fieldName : fields) {
Object val = jsonMap.get(fieldName);
if (val != null) {
resMap.put(fieldName, val);
}
}
for (Entry<String, Object> entry : jsonMap.entrySet()) {
if (orderedFields.contains(entry.getKey())) {
continue;
}
resMap.put(entry.getKey(), entry.getValue());
}
try {
return objectMapper.writeValueAsString(resMap);
} catch (JsonProcessingException e) {
throw new RuntimeException("Error converting map to json", e);
}
}
#Test
public void jsonReorder_validInput_reorderedOutput() {
String src = "{\"b\":2, \"c\": 3, \"a\":1}";
String res = reorderFieldsInJson(src, new String[] {"a", "b"});
Assertions.assertEquals("{\"a\":1,\"b\":2,\"c\":3}", res);
}
}
Result on Java 11 and jackson 2.11.3:
org:
{"b":2, "c": 3, "a":1}
ordered:
{"a":1,"b":2,"c":3}
I'm trying a simple test where the code appends a few json entries, however it is getting overwritten each time (the json file will only have 1 entry in it after running). I know I need to somehow create an array in JSON using '[]', but how would I go about doing that? Also, is there a better way to be doing this? I've been searching around and every library seems clunky with lots of user written code. Thanks
public class REEEE {
private static Staff createStaff() {
Staff staff = new Staff();
staff.setName("mkyong");
staff.setAge(38);
staff.setPosition(new String[] { "Founder", "CTO", "Writer" });
Map<String, Double> salary = new HashMap() {
{
put("2010", 10000.69);
}
};
staff.setSalary(salary);
staff.setSkills(Arrays.asList("java", "python", "node", "kotlin"));
return staff;
}
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
File file = new File("src//j.json");
for(int i = 0; i < 4; i++) {
Staff staff = createStaff();
try {
// Java objects to JSON file
mapper.writeValue(file, staff);
// Java objects to JSON string - compact-print
String jsonString = mapper.writeValueAsString(staff);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
You can add staff in List and then write the list to file as below,
List<Staff> staffList = new LinkedList<>()
for(int i = 0; i < 4; i++) {
Staff staff = createStaff();
staffList.add(staff);
}
mapper.writeValue(file, staffList);
Hope it helps.
Jackson was implemented to parse and generate JSON payloads. All extra logic related with adding new element to array and writing back to file you need to implement yourself. It should not be hard to do:
class JsonFileAppender {
private final ObjectMapper jsonMapper;
public JsonFileAppender() {
this.jsonMapper = JsonMapper.builder().build();
}
public void appendToArray(File jsonFile, Object value) throws IOException {
Objects.requireNonNull(jsonFile);
Objects.requireNonNull(value);
if (jsonFile.isDirectory()) {
throw new IllegalArgumentException("File can not be a directory!");
}
JsonNode node = readArrayOrCreateNew(jsonFile);
if (node.isArray()) {
ArrayNode array = (ArrayNode) node;
array.addPOJO(value);
} else {
ArrayNode rootArray = jsonMapper.createArrayNode();
rootArray.add(node);
rootArray.addPOJO(value);
node = rootArray;
}
jsonMapper.writeValue(jsonFile, node);
}
private JsonNode readArrayOrCreateNew(File jsonFile) throws IOException {
if (jsonFile.exists() && jsonFile.length() > 0) {
return jsonMapper.readTree(jsonFile);
}
return jsonMapper.createArrayNode();
}
}
Example usage with some usecases:
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public class JsonPathApp {
public static void main(String[] args) throws Exception {
Path jsonTmpFile = Files.createTempFile("json", "array");
JsonFileAppender jfa = new JsonFileAppender();
// Add POJO
jfa.appendToArray(jsonTmpFile.toFile(), createStaff());
printContent(jsonTmpFile); //1
// Add primitive
jfa.appendToArray(jsonTmpFile.toFile(), "Jackson");
printContent(jsonTmpFile); //2
// Add another array
jfa.appendToArray(jsonTmpFile.toFile(), Arrays.asList("Version: ", 2, 10, 0));
printContent(jsonTmpFile); //3
// Add another object
jfa.appendToArray(jsonTmpFile.toFile(), Collections.singletonMap("simple", "object"));
printContent(jsonTmpFile); //4
}
private static Staff createStaff() {
Staff staff = new Staff();
staff.setName("mkyong");
staff.setAge(38);
staff.setPosition(new String[]{"Founder", "CTO", "Writer"});
Map<String, Double> salary = new HashMap<>();
salary.put("2010", 10000.69);
staff.setSalary(salary);
staff.setSkills(Arrays.asList("java", "python", "node", "kotlin"));
return staff;
}
private static void printContent(Path path) throws IOException {
List<String> lines = Files.readAllLines(path);
System.out.println(String.join("", lines));
}
}
Above code prints 4 lines:
1
[{"name":"mkyong","age":38,"position":["Founder","CTO","Writer"],"salary":{"2010":10000.69},"skills":["java","python","node","kotlin"]}]
2
[{"name":"mkyong","age":38,"position":["Founder","CTO","Writer"],"salary":{"2010":10000.69},"skills":["java","python","node","kotlin"]},"Jackson"]
3
[{"name":"mkyong","age":38,"position":["Founder","CTO","Writer"],"salary":{"2010":10000.69},"skills":["java","python","node","kotlin"]},"Jackson",["Version: ",2,10,0]]
4
[{"name":"mkyong","age":38,"position":["Founder","CTO","Writer"],"salary":{"2010":10000.69},"skills":["java","python","node","kotlin"]},"Jackson",["Version: ",2,10,0],{"simple":"object"}]
I am trying to understand the concept of Strong and Causal consistency by implementing it in Multi-threaded Java. I have written the following code using the Vert.x framework. I am trying to implement the following:
Strong Consistency
Every PUT (write) request is atomic across all replicas.
At any point in time, only 1 PUT request per key can be performed on the datacenter instances.
A GET operation per key is to be blocked if a PUT operation for the same key is being processed.
The locking of datacenters is to be done at key level i.e. operations on multiple keys can run in parallel.
Causal Consistency
ALL PUT operations per key must be seen in all the datacenters in the same order.
At any point in time, different operations can be performed in different datacenters in parallel. That is, lock only one datacenter at a time for an operation per key.
A GET operation returns the value immediately without being blocked even if it is stale.
API on the Vert.x server
Here are the following GET and PUT operations that the Vert.x server will receive and must implement:
Vertx-DNS:8080/put?key=KEY&value=VALUE
This endpoint will receive the key, value pair that needs to be stored in the datacenter instances
Vertx-DNS:8080/get?key=KEY&loc=LOCATION
This endpoint will receive the key for which the value has to be returned by the Vertx server. The server has to return the value as the response to this request. The location value is 1 for datacenter1, 2 for datacenter2 and 3 datacenter3.
KeyValueLib.PUT(String datacenterDNS, String key, String value) throws IOException
This API method will put the value for the specified key in the specified datacenter instance.
KeyValueLib.GET(String datacenterDNS, String key) throws IOException
This API method returns the value for the specified key from the specified datacenter.
Code
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.TimeZone;
import java.util.Iterator;
import java.util.Collections;
import java.util.List;
import java.sql.Timestamp;
import org.vertx.java.core.Handler;
import org.vertx.java.core.MultiMap;
import org.vertx.java.core.http.HttpServer;
import org.vertx.java.core.http.HttpServerRequest;
import org.vertx.java.core.http.RouteMatcher;
import org.vertx.java.platform.Verticle;
public class Coordinator extends Verticle {
//Default mode: Strongly consistent. Possible values are "strong" and "causal"
private static String consistencyType = "strong";
/**
* TODO: Set the values of the following variables to the DNS names of your
* three dataCenter instances
*/
private static final String dataCenter1 = "ec2-52-2-18-9.compute-1.amazonaws.com";
private static final String dataCenter2 = "ec2-52-2-12-29.compute-1.amazonaws.com";
private static final String dataCenter3 = "ec2-52-2-10-12.compute-1.amazonaws.com";
#Override
public void start() {
//DO NOT MODIFY THIS
KeyValueLib.dataCenters.put(dataCenter1, 1);
KeyValueLib.dataCenters.put(dataCenter2, 2);
KeyValueLib.dataCenters.put(dataCenter3, 3);
final RouteMatcher routeMatcher = new RouteMatcher();
final HttpServer server = vertx.createHttpServer();
server.setAcceptBacklog(32767);
server.setUsePooledBuffers(true);
server.setReceiveBufferSize(4 * 1024);
routeMatcher.get("/put", new Handler<HttpServerRequest>() {
#Override
public void handle(final HttpServerRequest req) {
MultiMap map = req.params();
final String key = map.get("key");
final String value = map.get("value");
//You may use the following timestamp for ordering requests
final String timestamp = new Timestamp(System.currentTimeMillis()
+ TimeZone.getTimeZone("EST").getRawOffset()).toString();
Thread t = new Thread(new Runnable() {
public void run() {
//TODO: Write code for PUT operation here.
//Each PUT operation is handled in a different thread.
//Use helper functions.
try{
switch(consistencyType) {
case "strong":
//Do
break;
case "causal":
//Do
break;
default: continue;
}
}
}
});
t.start();
req.response().end(); //Do not remove this
}
});
routeMatcher.get("/get", new Handler<HttpServerRequest>() {
#Override
public void handle(final HttpServerRequest req) {
MultiMap map = req.params();
final String key = map.get("key");
final String loc = map.get("loc");
//You may use the following timestamp for ordering requests
final String timestamp = new Timestamp(System.currentTimeMillis()
+ TimeZone.getTimeZone("EST").getRawOffset()).toString();
Thread t = new Thread(new Runnable() {
public void run() {
//TODO: Write code for GET operation here.
//Each GET operation is handled in a different thread.
//Highly recommended that you make use of helper functions.
req.response().end("0"); //Default response = 0
}
});
t.start();
}
});
routeMatcher.get("/consistency", new Handler<HttpServerRequest>() {
#Override
public void handle(final HttpServerRequest req) {
MultiMap map = req.params();
consistencyType = map.get("consistency");
req.response().end();
}
});
routeMatcher.noMatch(new Handler<HttpServerRequest>() {
#Override
public void handle(final HttpServerRequest req) {
req.response().putHeader("Content-Type", "text/html");
String response = "Not found.";
req.response().putHeader("Content-Length",
String.valueOf(response.length()));
req.response().end(response);
req.response().close();
}
});
server.requestHandler(routeMatcher);
server.listen(8001);
}
}
KeyValueLib.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
public class KeyValueLib {
public static HashMap<String, Integer> dataCenters = new HashMap();
private static String URLHandler(String string) throws IOException {
StringBuilder stringBuilder = new StringBuilder();
try {
String string2;
URL uRL = new URL(string);
HttpURLConnection httpURLConnection = (HttpURLConnection) uRL
.openConnection();
if (httpURLConnection.getResponseCode() != 200) {
throw new IOException(httpURLConnection.getResponseMessage());
}
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(httpURLConnection.getInputStream()));
while ((string2 = bufferedReader.readLine()) != null) {
stringBuilder.append(string2);
}
bufferedReader.close();
httpURLConnection.disconnect();
} catch (MalformedURLException var2_3) {
var2_3.printStackTrace();
}
return stringBuilder.toString();
}
public static void PUT(String string, String string2, String string3)
throws IOException {
String string4 = String.format("http://%s:8001/put?key=%s&value=%s",
string, string2, string3);
String string5 = KeyValueLib.URLHandler(string4);
try {
switch (dataCenters.get(string)) {
case 1 : {
break;
}
case 2 : {
Thread.sleep(200);
break;
}
case 3 : {
Thread.sleep(800);
break;
}
}
} catch (InterruptedException var5_5) {
// empty catch block
}
if (!string5.equals("stored")) {
System.out.println("Some error happened");
}
}
public static String GET(String string, String string2) throws IOException {
String string3 = String.format("http://%s:8001/get?key=%s", string,
string2);
String string4 = KeyValueLib.URLHandler(string3);
return string4;
}
}
Can someone help me how to implement this?
I'm trying to use HAshmap in a class in order to, from other classes, look up product descriptions given the product code.
Whith the setter (populate) everything seems to work fine , but when I'm tryig to use a getter (getdesc) i get an error.
The csv file i'm using has only 2 filds (cod,des). Later, I plan to populate the hashmap from JDBC SQL server source.
I'm probabbly using the wrong syntax. I'll apreciate if anyone can help.
That's my current class code:
package bookRecommender;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
public class ProdutoDescricao
{
public static void main(String[] args) {}
#SuppressWarnings({ "resource", "unused" })
public static void populate(String[] args) throws IOException {
Map<String, ArrayList<String>> produtos=null;
try {
String csvFile = "Data/produto_descricao.csv";
BufferedReader br = new BufferedReader(new FileReader(csvFile));
String line = "";
StringTokenizer st = null;
produtos= new HashMap<String, ArrayList<String>>();
int lineNumber = 0;
int tokenNumber = 0;
while ((line = br.readLine()) != null) {
lineNumber++;
st = new StringTokenizer(line, ",");
while (st.hasMoreTokens()) {
tokenNumber++;
String token_lhs=st.nextToken();
String token_rhs= st.nextToken();
ArrayList<String> arrVal = produtos.get(token_lhs);
if (arrVal == null) {
arrVal = new ArrayList<String>();
produtos.put(token_lhs,arrVal);
}
arrVal.add(token_rhs);
}
}
System.out.println("Final Hashmap is : "+produtos);
} catch (Exception e) {
System.err.println("CSV file cannot be read : " + e);
}
}
public String getdesc (long cod)
{
return produto.get(cod);
//Here is the sysntax error
}
}
produtos= new HashMap<String, ArrayList<String>>() produtos it has no values it is blank.
ArrayList<String> arrVal = produtos.get(token_lhs); this line has issue, you have to first add values in your map then get those values.
You have a map with String key and ArrayList values types, but you trying to retrieve value with long key and String values type.
public ArrayList<String> getdesc (String cod)
{
return produtos.get(cod);
}
Also declare field 'produtos':
private static Map<String, ArrayList<String>> produtos;
Full class code: http://pastebin.com/QLZryqT8