convert TreeMap<String,Object> to List<HashMap<String,Object>> - list

I have a TreeMap<String,Object> which contains Objects that are actually HashMap<String,Object>. I want to convert this to List<HashMap<String,Object>>. I was trying to convert it using Java 8 and wrote the following code which is giving compilation error due to conversion from List<Object> to List<HashMap<String,Object>>.
public static void main(String[] args) {
TreeMap<String,Object> treeMap = new TreeMap<String,Object>();
HashMap<String,Object> map1 = new HashMap<String,Object>();
map1.put("a",1);
map1.put("b","2");
map1.put("c",5);
treeMap.put("01",map1);
HashMap<String,Object> map2 = new HashMap<String,Object>();
map2.put("a",5);
map2.put("b","7");
map2.put("c",6);
treeMap.put("02",map2);
//this conversion is not working as Java is not allowing to convert from List<Object> to List<HashMap<String,Object>>
List<HashMap<String,Object>> list= treeMap.values().stream()
.collect(Collectors.toList());
}
Changing the TreeMap to TreeMap<String,HashMap<String,Object>> works but I don't want to make this change as I am passing this to a separate method which expects TreeMap<String,Object>.
Please suggest.

Well, you define the treeMap to have Object values, this is why values().stream() returns a Stream<Object>. Either change your contract or you'll need to cast the elements in the stream:
List<HashMap<String,Object>> list= treeMap.values().stream()
.map(element -> (HashMap<String,Object>)element)
.collect(Collectors.toList());

I would start by giving treeMap the proper types: TreeMap<String, HashMap<String, Object>>.
You can then wrap the map and pass new TreeMap<String, Object>(treeMap) to that other method.
Nicer, as it does not require a new map, would be to follow Sean's comment and change that method's parameter from TreeMap<String, Object> to TreeMap<String, ?>, if you are allowed to do that.

Related

how to pass all List<String> native methods to a List<Random>?

I'm new in Flutter(Dart) and I came across this problem. All lists of the type String naturally have the string methods like item.length, item.contains and so on. But when you create a random List type, it gets none of that. What is the recommended way of inherit all List properties to the custom one?
You probably didn't provide a list type and you can't see String methods.
void main() {
List<String> names = ['Dave', 'Ana', 'Robert'];
names.shuffle();
for(var name in names) {
print('name: $name, lenght: ${name.length}');
}
}

Mockito Junit for returning List

I want to write junit for this method returning country List
public List<String> getCountries(String countryCd) {
String sql = "select COUNTRY_NAME from MY_COUNTRY WHERE COUNTRY_CD = :countryCd ";
List<String> countries;
SqlParameterSource parameters = new MapSqlParameterSource().addValue("countryCd", countryCd);
countries = namedParameterJdbcTemplate.query(sql,parameters, (resultSet, rowNum) ->
resultSet.getString("COUNTRY_NAME")));
return countries
}
I tried something like this
Mockito.when(namedParameterJdbcTemplate.queryForObject(queryJobs, parameters, String.class))
MapSqlParameterSource inherits its equals method from Object.
This means that 2 parameter sources are equal only if they reference same instance.
You need to provide an argument matcher to compare this argument and not use equals method. The cleanest way to do it is via Custom Argument Matcher.
Alternatively, you relax the requirements for this argument and use any(MapSqlParameterSource.class) matcher.
try using
Mockito.when(namedParameterJdbcTemplate.queryForObject(any(), any(), any())).thenRetrun(you v

How to override KeyValuePair<TKey, TValue> in C#?

I want to override the default structure of KeyValuePair in C#, so that I can make a KeyValuePair to accept a 'var' types.
Something like this :
List<KeyValuePair<string, var>> kvpList = new List<KeyValuePair<string, var>>()
{
new KeyValuePair<string, var>("Key1", 000),
new KeyValuePair<string, var>("Key2", "value2"),
new KeyValuePair<string, var>("Key3", 25.45),
};
Even if its possible for dictionary, then also it will solve my problem.
You could use object as your type, and then cast to/from object to desired outcomes. However, it's important to note that this is very much the opposite of object oriented programming, and generally indicates an error in your design and architecture.
Hmm I am wondering if this might help you: To have a list as you want, it is really possible BUT the "var" type (as you named it) must be the same for all KeyValuePair instances. For having whatever type you must use object or dynamic (use Haney's answer).
So considering that you want a single type for all KeyValuePair instances, here is a solution:
Firstly, create this helper class:
public static class KeyValuePairExtentions
{
public static List<KeyValuePair<string, T>> GetNewListOfType<T>(Expression<Func<T>> type)
{
return new List<KeyValuePair<string, T>>();
}
public static void AddNewKeyValuePair<T>(this List<KeyValuePair<string, T>> #this, string key, T element)
{
#this.Add(new KeyValuePair<string, T>(key, element));
}
}
To consume these functions, here is an example:
var lst = KeyValuePairExtentions.GetNewListOfType(() => new {Id = default (int), Name = default (string)});
lst.AddNewKeyValuePair("test1", new {Id = 3, Name = "Keith"});
The ideea is to rely on the powerfull type inference feature that we have in C#.
Some notes:
1) if T is anonymous and you create a new instance of a list in an assembly and consume it in another assembly it is VERY possible that this will NOT work due to the fact that an anonymous type is compiled per assembly (in other words, if you have a variable var x = new { X = 3 } in an assembly and in another var y = new { X = 3 } then x.GetType () != y.GeTType () but in the same assembly types are the same.)
2) If you are wondering whether an instance it's created or not by calling GetNewListOfType, the answer is NO because it is an expression tree function and the function is not even compiled. Even with a Func will work because I am not calling the function in my code. I am using the function just for type inference.

Dropwizard /Jersey: Pass query-parameter with multiple values as List (maybe using a filter)

I have clients passing in IDs like this: /v1/path?id=1,2,3
What I have and want
I have a resource class for Dropwizard/Jersey.
I'd like to show up the query-parameter id=1,2,3 as a List parameter in my resource's GET method
// Resource class
public List<Something> getFilteredList(#QueryParam("id") List<String> ids) {
// filter the List<Something> based on a list of ids
}
Right now, the ids list contains 1 string which is "1,2,3".
What I tried
I tried a filter but the query parameters given by Jersey's
ContainerRequestContext.getUriInfo().getQueryParameters()
is immutable.
Questions
I would like to apply a filter and change any comma separated query parameters into multi-valued parameters so that the resource method gets a list instead.
Is there a way to change the existing query parameters using a Jersey filter?
What's a good way to solve this problem?
The best way I can think of is to just create a wrapper class for the list. This makes it easier to take advantage of the specified functionality of Jersey. You can see what I mean at Passing custom type query parameter.
For example
public class IdFilter {
private List<String> ids = new ArrayList<>();
public List<String> getIds() { return ids; }
public static IdFilter valueOf(String param) {
IdFilter filter = new IdFilter();
for (String id: param.split(",") {
filter.getIds().add(id);
}
}
}
getFilteredList(#QueryParam("id") IdFilter ids) {
We don't need to do anything else. Just having the static valueOf is enough for Jersey to know how to parse the query string.
3 ways to solve it:
use the generic context-parameter UriInfo , which is not very expressive
add an explicit custom type that can parse a comma-separated list
stay with #QueryParam List<String> requiring a concatenated query like ?id=1&id=2&id=3 given as URI
I would prefer the second as most-expressive, like answered already by Paul. This way you can concisely pass a single CSV like ?id=1,2,3,3 and also use a Set to ensure unique ID values, e.g. resulting in only [1, 2, 3].
Generic context-param UriInfo
One way would be to use a generic parameter #Context UriInfo to get the list in the method's body:
public List<Something> getFilteredList( #Context UriInfo uriInfo ) {
List<String> idList = uriInfo.getQueryParameters().get("id"); // before was #QueryParam("id")
System.out.println("idList: " + idList);
// filter a given list by ids
var somethingFiltered = getSomethingList().stream()
.filter(s -> idList.contains(s.getId()))
.collect(toList());
return Response.status(Status.OK).entity(somethingFiltered).build();
}
See the tutorial in Java Vogue(2015): QueryParam Annotation In Jersey -
Custom type with static valueOf(String) factory-method
The other way is to design a custom type which can be constructed using a String:
class IdSet {
Set<String> values;
// a factory method, can also be named valueOf
public static IdSet fromString(String commaSeparated) {
return new HashSet( Arrays.asList( commaSeparated.split(",") ) );
}
}
public List<Something> getFilteredList(#QueryParam("id") IdSet ids) {
System.out.println("ids (Set): " + ids.values);
// filter a given list by ids
var somethingFiltered = getSomethingList().stream()
.filter(s -> ids.values.contains(s.getId()))
.collect(toList());
return Response.status(Status.OK).entity(somethingFiltered).build();
}
See Jersey's JavaDocs for #QueryParam:
The type T of the annotated parameter, field or property must either:
Be a primitive type
Have a constructor that accepts a single String argument
Have a static method named valueOf or fromString that accepts a single String argument (see, for example, Integer.valueOf(String))
Have a registered implementation of ParamConverterProvider that returns a ParamConverter instance capable of a "from string" conversion for the type.
Be List<T>, Set<T> or SortedSet<T>, where T satisfies 2, 3 or 4 above. The resulting collection is read-only.
Use a collection interface with multiple key-value pairs
When the calling client uses following URI pattern: /something?id=1&id=2&id=3 then JAX-RS can deserialize them to a single parameter of List<String> id having given multiple elements:
public List<Something> getFilteredList(#QueryParam("id") List<String> ids) {
System.out.println("ids : "+ids);
// filter a given list by ids
var somethingFiltered = getSomethingList().stream()
.filter(s -> ids.contains(s.getId()))
.collect(toList());
return Response.status(Status.OK).entity(somethingFiltered).build();
}
See Mkyong: JAX-RS #QueryParam example where explained the multiple occurrences of orderBy in the GET query:
#QueryParam will convert the query parameter “orderBy=age&orderBy=name” into java.util.List automatically.
See also
Handling Multiple Query Parameters in Jersey
Deserializing List<Map<String, String>> QueryParam in jersey 1
Jersey, #QueryParam List<String>

Combining lists into an arraylist (C#)

I have a list and I want to copy three other lists into it.
// The main list
List<List<string>> list= new List<List<string>>();
// The lists which I want to combine
ArrayList sublist1= new ArrayList();;
ArrayList sublist2= new ArrayList();;
ArrayList sublist3= new ArrayList();;
What I tried is:
list[0].AddRange(sublist1);
list[0].AddRange(sublist2);
list[0].AddRange(sublist3);
It doesn't work because It is multidimensional list. I need this type of list for the future plans.
How can I accomplist it?
As already mentioned in comments just use List<string> instead of ArrayList.
It has nothing to do about multidimensional arrays, just types mismatch.
Then you say List<List<string>> it basically means create list type, which will contain List<string> as items (the part in angle brackets), so you need to add them, not ArrayLists. Similarly List<string> means type of list which will contain string as items.
As in the comments, you need to pass a type that follows IEnumerable. For example, you can change your ArrayLists to List
// The main list
List<List<string>> list = new List<List<string>>();
// The lists which I want to combine
var sublist1 = new List<string>();
var sublist2 = new List<string>();
var sublist3 = new List<string>();
list[0].AddRange(sublist1);
list[0].AddRange(sublist2);
list[0].AddRange(sublist3);
change type of sublists to some IEnumerable<string> (string[] or List<string> or something else)
var sublist1 = new string[] {};
var sublist2 = new string[] {};
var sublist3 = new string[] {};
OR do cast
list[0].AddRange((IEnumerable<string>) sublist1);
list[0].AddRange((IEnumerable<string>) sublist2);
list[0].AddRange((IEnumerable<string>) sublist3);
Because you are trying to use AddRange method of System.Collections.Generic.List<T>
and the signature of this method is
public void AddRange(System.Collections.Generic.IEnumerable<T> collection)
so it requires IEnumerable as a parameter.