aerospike JUNIT Record Constructor not working - java

I am writing aeropsike junit test cases for my test cases. For Storing aerospike bins, i am using ConcurrentHashMap.
// InMemory Map for storing AeroSpike Related Data...
ConcurrentMap<String, Bin[]> aerospike_keyBins = new ConcurrentHashMap<String, Bin[]>();
// InMemory Map for storing AeroSpike Related Data...
ConcurrentMap<String, Integer> aerospike_keyGen = new ConcurrentHashMap<String, Integer>();
Storing of bins and GenNumber related information is working perfectly fine.
But i am facing issues while getting record from map (Actually converting bins values from Map to Aerospike Record).
Here is the function which is expected to convert the same.
private Record binsToRecord(String stringKey, Bin... bins) {
Map<String, Object> mapOfBins = new HashMap<String, Object>();
for (Bin bin : bins) {
mapOfBins.put(bin.name, bin.value);
}
return new Record(mapOfBins, aerospike_keyGen.get(stringKey), 1);
}
While Calling new Record in that function i am getting following error message.
java.lang.ClassCastException: com.aerospike.client.Value$StringValue cannot be cast to java.lang.String
at com.aerospike.client.Record.getString(Record.java:66)
On Debugging this issue, i found that in Record.class of Aerospike,
following function is giving error.
/**
* Get bin value as String.
*/
public String getString(String name) {
return (String) getValue(name);
}
getValue is returning correct value but (String) getValue(name) throwing error.
Any clue about why am i getting this error ?

Your binsToRecord method looks fine.
/**
* Get bin value as String.
*/
public String getString(String name) {
return (String) getValue(name);
}
Here in the Bin binValue is a StringValue object so you can't directly cast it to String.
try
(getValue(name)).toString()
// StringValue object provide toString() method.

Actually the problem was while putting values to local hashmap.
I was pushing StringValues type of values in local hashmap Fixing that to put Standard String fixed the problem.
Here is the new binsToRecordfunction.
/*
* Convert Bin Set to Record Object.
*/
private Record binsToRecord(String stringKey, Bin... bins) {
Map<String, Object> mapOfBins = new HashMap<String, Object>();
for (Bin bin : bins) {
if (bin.value instanceof Value.StringValue)
mapOfBins.put(bin.name, bin.value.toString());
else if (bin.value instanceof Value.LongValue)
mapOfBins.put(bin.name, bin.value.toLong());
else if (bin.value instanceof Value.DoubleValue)
mapOfBins.put(bin.name, bin.value.toLong());
}
return (new Record(mapOfBins, aerospike_keyGen.get(stringKey), 1));
}

Related

Java - JSON output is not expected as what console suggests

I'm new to Java and writing APIs.
I basically have two things: a HashMap called db that should be returned as a JSON and an ArrayList called defaultParameters. Basically what the application does are the following:
db basically contains an array of objects of key-value pairs that should be returned as a JSON when a user makes a GET request to this address.
defaultParameters is basically a list of default key-value pairs. If there is no key-value pair within that object, then that object takes in that default key-value pair.
I was able to get it to display on the console, but for some reason, the updated values are not appearing in the JSON when I do the get request.
Here are the relevant code snippets:
private static ArrayList<Item> DB = new ArrayList<>();
private static HashMap<String, String> defaultValues = new HashMap<>();
private void updateAllItems(){
for(Item item : DB){
for(Map.Entry entry : defaultValues.entrySet()){
String currentField = (String) entry.getKey();
String currentValue = (String) entry.getValue();
item.addField(currentField, currentValue);
}
}
}
#GET
#Produces(MediaType.APPLICATION_JSON)
public Response getAllItems() {
updateAllItems();
for(Item item : DB){
// Test code that I added
item.printItem();
}
return Response.ok(DB).build();
}
Snippets of the Item class
public class Item {
private HashMap<String, String> item = new HashMap<>();
public void addField(String key, String value){
item.put(key, value);
}
public void printItem(){
for(Map.Entry entry : item.entrySet()){
String currentField = (String) entry.getKey();
String currentValue = (String) entry.getValue();
System.out.println(currentField + ": " + currentValue);
}
}
}
Doing the POST request and doing the GET request yields the following:
On the console (Something: notsomething) is new:
seller: Mrs. Fields
price: 49.99
title: Cookies
category: 42
something: notsomething
The JSON response however:
[{"category":"42","seller":"Mrs. Fields","price":"49.99","title":"Cookies"}]
The JSON is missing the new key-value pair that the console has. I'm trying to have the JSON reflect what the console is doing. Anyone have any ideas?
Alright, after some thinking, I figured out what to do.
I changed my code from
public class Item {
to
public class Item extends HashMap<String, String> {
and removed
private HashMap<String, String> item = new HashMap<>();
which means I had to change item to this. I figured since that I'm going to be using each instance as a hashmap, I may as well extend the hashmap that will change the instance of the item too.
Thanks for everyone's help. The comment gave me some more insight of what I was trying to do which led to a solution.

fill an HashMap with elements of a set passed as parameter

i have to write the method:
public Map<Robot, Integer> PickedUpForEachRobot(Set<Stuff> pickedUp)
which has to iterate through the set passed as parameter and has to count the quantity of stuff picked up by each robot and associate it to his instance.
what i have done is this:
public Map<Robot, Integer> PickedUpForEachRobot(Set<Stuff> pickedUp) {
final Map<Robot,Integer> map = new HashMap<>();
for(Stuff stuff : pickedUp){
Integer quantity = map.get(stuff.getPicker());
if(quantity!=null){
map.put(stuff.getPicker(), quantity);
}
}
return map;
}
I also have other classes:
public class Stuff {
private Robot picker;
public Robot getPicker() {
return this.picker;
}
}
and:
public class Robot {
private Set<Stuff> bunchOfStuff;
public Set<Stuff> getBunchOfStuff() {
return this.bunchOfStuff;
}
}
for which i have tried to be synthetic, so i hope i can be clear anyway.
So my problem is that when i do a test for this method:
#Test
public void testRaccoltoPerMezzo() {
Statistics stats = new Statistics();
Stuff stuff1 = new ball();
Stuff stuff2 = new legoPiece();
Set<Stuff> set = new HashSet<>();
set.add(stuff1);
assertEquals(1,set.size());
Map<Robot,Integer> map = new HashMap<>();
map.put(stuff1.getPicker(),1);
assertEquals(map, stats.PickedUpForEachRobot(set));
}
it fails and it says to me:
java.lang.AssertionError: expected:<{null=1}> but was:<{}>
and i can't understand why. Can somebody help me?
This message :
java.lang.AssertionError: expected:<{null=1}> but was:<{}>
means that you expect to have a map with one element that owns a null key and as associated value 1 but you got a empty map.
The expected map you have created doesn't seem to be adequate according to your requirement and the actual map either.
About the populating of the map in the implementation, I noticed at least this point that is not at all logical.
Here :
final Map<Robot,Integer> map = new HashMap<>();
for(Stuff stuff : pickedUp){
Integer quantity = map.get(stuff.getPicker());
if(quantity!=null){
map.put(stuff.getPicker(), quantity);
}
}
Integer quantity = map.get(stuff.getPicker()); will always value quantity to null as you get it from an empty map : map = new HashMap<>(); and you populate the map only if quantity is not null :
if(quantity!=null){
map.put(stuff.getPicker(), quantity);
}
But it will never happen as the map is empty : so you never populate the map.
You have probably other issues in the code but I hope it will help you to rework your logic.

Get Key from a specified Value in HashMap

I have a HashMap "stateCityMap" which is a Map>. the Keys are the States ie Goa,Kerala etc and the Values are the Cities ie Panjim,Margao etc. I want to Check if a particular city is present in the HashMap, eg.Margao and give the corresponding key of that value as the result..but everytime i ran the below code.it performs the else part(when the city is not present in the HashMAp).
city :- is the name of the city I pass to this function
Code:
public String getState(Map<String, List<String>> stateCityMap, String city) throws CityNotFoundException {
HashMap<String, List<String>> g = new HashMap<String, List<String>>(stateCityMap);
if(g.containsValue(city)){
System.out.println("State:- " +g.get(city));
}
else {
throw new CityNotFoundException("City Not Found");
}
return null;
}
Why is it doing that? why am I getting the wrong result?
It's not efficient, but you need to scan through each list in the map:
public String getState(Map<String, List<String>> stateCityMap, String city) throws CityNotFoundException {
for (Map.Entry<String, List<String>> entry : stateCityMap.entrySet()) {
if (entry.getValue().contains(city)) {
return entry.getKey();
}
}
throw new CityNotFoundException("City Not Found");
}
containsValue method returns true if the map maps one or more keys to the specified value.
In your case type of value is List, but you are calling containsValue method by passing String. So it will always returns false.
Since your value type is List, you will end up iterating all keys and all values to find if a city exists in any of the lists.
Better is to maintain two maps. Challenge will be to make sure that both maps always get updated (insert, delete, update) correctly.
Hope that helps.

How do I access the values in an object inside a HashMap

I'm attempting to access values that are held inside a Class which is listed in a HashMap.
In my first class I create a HashMap which links to the "LiftingStats" class.
Map<String, LiftingStats> fitnessGoals = new HashMap<String, LiftingStats>();
In the LiftingStats class I do the following...
public class LiftingStats
{
public String activity;
public String weightType;
public int weight;
public double difficulty;
/**
* Constructor for objects of class LiftingStats
*/
public LiftingStats()
{
this.run();
}
/**
* test method to fill values
*/
public void run(){
//code
this.activity = "bench press";
this.weightType = "Kg";
this.weight = 100;
this.difficulty = 8.5;
}
I'm running a test method to fill the hashmap with some values
public void testMethod(){
fitness.put("activityone", new LiftingStats());
fitness.put("activitytwo", new LiftingStats());
There are many ways to access them.
For retrieving the value of a specific key entry
LiftingStats valueForOne = fitness.get("activityone");
For retrieving values without concern for keys
Collection<LiftingStats> values = fitness.values();
For retrieving key and value pairs
Set<Map.Entry<String, LiftingStats>> entries = fitness.entrySet();
for (Map.Entry<String, LiftingStats> entry : entries) {
entry.getValue();
}
or some variant.
A Map is a Data Structure consisting of Key, Value pairs. In this case you have two keys that reference two instances of LiftingStats objects. To access these objects simply use your specific key to retrieve the object(s). Ex:
LiftingStats current = fitness.get("activityone");
With your reference to current you can perform operations on that specific LiftingStats object.
Similarly, you can 'daisy-chain' function calls together like this and still mutate the object within the Map. Ex:
fitness.get("activityone").someMethod();
You can adapt this answer to your problem :
How to efficiently iterate over each Entry in a Map?
Map<String, LiftingStats> fitnessGoals = new HashMap<String, LiftingStats>();
for (Map.Entry<String, LiftingStats> entry : fitnessGoals.entrySet())
{
//What you need to do with your map
}
Another way by which you can access variables of an object in HashMap is by typecasting the data fetched by getValue() method of a Hashmap into the user defined class.
You can use the following code:
Map<String, LiftingStats> lstats= new HashMap<String, LiftingStats>();
for (Map.Entry ls:lstats.entrySet()) {
System.out.println(ls.getKey()+" "+((LiftingStats)ls.getValue()).activity);
}
Any variable present in the class can be accessed simply by using ((LiftingStats)ls.getValue()).Var_name . where Var_name is the name of any class variable.

How to edit Hibernate Search java Source Code, or maybe a workaround?

I am trying to add FullTextFilters to my FullTextQuery in hibernate and there is only the method FullTextFilter.setParameter(String name, Object value)
I am trying to make a flexible, generic function to add filters to the query based on the entity its searching for, some have one parameter, some have two for their filters, so I would like to add a method to FullTextFilterImpl; setParameters(String[] names, String[] value) where I can pass in the names of all the parameters and probably a multidimensional array of the values for each parameter to transform my current code of
If( "checking which entity it is"){
fullTextQuery.enableFullTextFilter("FilterName").setParameter("firstFilter", "val1").setParameter("secondFilter", "val2");
}
else if("this entity's filter only has one parameter"){
fullTextQuery.enableFullTextFilter("FilterName").setParameter("firstFilter", "val1");
}
I tried creating a subclass of FullTextFilterImpl and putting a setParameters function in it, but the way this code is set up I'm not sure how to utilize it as FullTextQuery.enableFullTextFilter(filterName) returns a FullTextFilter object and then you call the setParameter() on that object. I'm not sure how I would get in the middle of that to do a setParameters
EDIT: I have downloaded the hibernate-search source code and added the following method to FullTextFilterImpl which I think will do what I want, but when I go to build it (even just the out-of-the-box project) I get all these checkstyle Only one new line is allowed at the end of a file errors. Is there something I'm missing from the hibernate quick-build guide.
public FullTextFilter setParameters(Map<String, List<String>> params){
for (String key : params.keySet()) {
List<String> values = params.get(key);
for(int i=0; i< values.size() ; i++){
parameters.put(key, values.get(i));
}
}
return this;
}
You can easily pass a Map of attributes to your custom Filter, the signature is:
FullTextFilter setParameter(String name, Object value);
so you could do
filter.setParameter( "myMap", properties );
where properties is an hashmap.
About the compilation error message:
Only one new line is allowed at the end of a file
is a message from checkstyle, it verifies code style is conforming to the Hibernate code style.
It's very simple to fix: there are multiple empty lines at the end of the source file, delete them. The error message should tell you what file needs to be polished.
if i correctly understand you question you need Builder pattern
here an example you could use :
public class FullTextFilter {
String[] keys;
Object[] objects;
private FullTextFilter(String[] keys, Object[] objects) {
}
public static FullTextFilterBuilder builder(){
return new FullTextFilterBuilder();
}
public static class FullTextFilterBuilder {
private Map<String, Object> parameters = new HashMap<String, Object>();
public FullTextFilterBuilder setParameter(String key, Object value){
parameters.put(key, value);
return this;
}
public FullTextFilter build(){
return new FullTextFilter(parameters.keySet().toArray(new String[0]), parameters.values().toArray(new Object[0]));
}
}
}
and then using it like this :
FullTextFilter filter = FullTextFilter.builder().setParameter("", new Object()).setParameter("", new Object()).build();
tell if that's what you are looking for.
if not i'll delete my answer
I presume you want this:
fullTextQuery.enableFullTextFilter("FilterName").setParameter("firstFilter", "val1").setParameter("secondFilter", "val2");
fullTextQuery{
name:"FilterName"
,parameters:["filter1":"value1", "filter2":"value2"]
}
static FullTextQuery enableFullTextFilter(String name){...}
FullTextQuery setParameter(String key, String value){
parameters.put(key, value);
return this;
}
assuming a parameters hashmap.
seeing as I was a little off base.. cant you do something like this?
setFilters (HashMap<String, String> filters) {
FullTTextFilter fl = FullTextQuery.enableFullTextFilter("filtername");
for (String key : filters.keySet()) {
fl.setParameter(key, filters.get(key));
}
}

Categories