AssertJ: FlatMap list of lists after calling extracting - java

So I have a Map of String/String list pairs, and what I want to do is after extraction, combine the returned lists into one list on which i can perform more assertions:
MyTest.java
Map<String, List<String>> testMap = new HashMap<>();
List<String> nameList = newArrayList("Dave", "Jeff");
List<String> jobList = newArrayList("Plumber", "Builder");
List<String> cityList = newArrayList("Dover", "Boston");
testMap.put("name", nameList);
testMap.put("job", jobList);
testMap.put("city", cityList);
assertThat(testMap).hasSize(3)
.extracting("name", "city")
//not sure where to go from here to flatten list of lists
// I want to do something like .flatMap().contains(expectedValuesList)
When I call extracting, it pulls out the list values into a list of lists, which is fine, but I cant call flatExtracting after that as there are no property names to pass in, and from what I've read it doesn't seem like a custom extractor would be appropriate(or else I'm not entirely sure how to put it together). Is there another way to flatten the list of lists im getting back? I could go a slightly longer route and do assertions on the list of lists, or use a lambda before the assert to collect the results but I'd like to keep the assertion as one(e.g. some map asserts then chain some assertions on the contents)

flatExtracting is not in the map assertions API (yet), what you can instead is:
assertThat(testMap)
.hasSize(3)
.extracting("name", "city", "job")
.flatExtracting(list -> ((List<String>) list))
.contains("Dave", "Jeff", "Plumber", "Builder", "Dover", "Boston");
I ended creating https://github.com/joel-costigliola/assertj-core/issues/1034 to support this use case

Related

How do I get the value of a dictionary that contains a list of dictionaries in java?

I am working on a programm in Java which contains a part where I get a couple of information from my Python Server. It is a Hashmap that looks like this:
{hid=null, art=CWE, produktgruppe=23, objekt=Küche, betrag=714.989990234375, iban=DE0212, id=2812, varten=[{art=2, lz_min=24, lz_max=36, faktor=null, zinssatz=0.5, kondnr=84}], status=979}
How can I get the value of the key "zinssatz".
I tried it with
mymap.get("zinssatz");
But that always returns zero. Which is probably because it can't find the key inside my hashmap because it is build like a "Dictionary with a list of dictionaries" inside it.
Thanks for your help.
It seems to be a nested map. Have you tried the following:
((HashMap)mymap.get("varten")).get("zinssatz");
Or, if you're not sure if varten is really a HashMap, you can try the following to get the type:
System.out.println(mymap.get("varten").getClass());
Update
If varten is a HashMap stored inside an ArrayList, try the following:
((HashMap)((ArrayList)mymap.get("varten")).get(0)).get("zinssatz");
...which is the same as:
List list = (ArrayList) mymap.get("varten");
Map map = (HashMap) list.get(0);
Object zinssatz = map.get("zinssatz");

Adding to existing map with Java stream

Map<Long, Employee.status> prevStatus = empRecords.stream()
.collect(Collectors.toMap(employeeRecord::getEmloyeeID,
employeeRecord::getEmployeeStatus));
I already have the above code, I need to add a similar operation but instead of creating a new Map I want to add the result to the existing map.
prevStatus = empRecords.stream()
.collect(Collectors.**toMap**(employeeRecord::getEmloyeeID,
employeeRecord::**getUSEmployeeStatus**));
You can create a new Map and add its entries to the existing Map:
prevStatus.putAll(
empRecords.stream()
.collect(Collectors.toMap(employeeRecord::getEmloyeeID,
employeeRecord::getUSEmployeeStatus)));
Or you can use forEach instead of collect:
empRecords.stream()
.forEach(emp -> prevStatus.put(emp.getEmloyeeID (),
emp.getEmployeeStatus()));
This is expected code
empRecords.stream()
.collect(Collectors.toMap(employeeRecord::getEmloyeeID,
employeeRecord::getEmployeeStatus,(newVal,oldVal)->newVal,()->existingMap));
Where (newVal,oldVal)->newVal logic is for what if key is already present in existing Map and
existingMap is your existing map. Make sure existingMap is not null. If it is null going with new HashMap what you shared in your code itself fine.

Read a list of parameters in order /1;2;3;4;5

Is it possible to read a parameter list like example.com/1;2;3;4;5 in the same order as provided by the URL?
My current not working approach is:
public Response(#PathParam("list") PathSegment list) {
Set<String> listParams = list.getMatrixParameters().keySet();
List<String> listList = new ArrayList<>(list.size() + 1);
listList.add(list.getPath());
for (String param : list) {
listList.add(param);
}
}
It does work for 1;2;3;4;5, but it does not work for 1;5;4;3;2. In both cases the output would be 1;2;3;4;5. The matrixParameters appear to be sorted alphabetically and not by the input order. Just reading the whole parameter as a String and parsing it manually would be fine, but couldn't find a way to do this either.
Please, take a careful look at the PathSegment documentation.
The matrix parameters are stored in MultivaluedMap. Its only implementation is MultivaluedHashMap. It does not preserve the order of the elements.
I've done a quick check how to get the raw request parameters in JAX-RS. There seems to be no pure JAX-RS way. You could try to work with the raw HttpServletRequest object as in this question to get the information.

How to dynamically create Lists in java without duplicate?

With reference to the similar question. How to dynamically create Lists in java?
I have quite a similar problem to the person asked.
In my project I have airplanes, airports and passengers for PNR record
The passenger destination airport is exported from database, but then I have to add it to a List of destination with name,airplanes.
So the database will contain like
A380, JFK, PersonA
A380, JFK, PersonB
A330, LHR, PersonC
My plan is to create the list of airport dynamically from the database and add those passenger with the same destination to it.
So currently I have peronsA and personB with JFK they will be in the same list. While in the LHR list only personC will be in LHR list, there will be hundreds of thousand record of such and hundreds of airport list to create, so I have to create such list dynamically.
But question is how do I determine if the the airport(JFK) list already exists and not create another list for that particular airport? Or is there another way to store information?
Pseudo code:
while (dbrecord =true){
if(passenger.destination == "JFK"){
List<passenger> JFK(dynamic)= new ArrayList<passenger>();
JFK(dynamic).add(passenger)
}
I'm not 100% sure if I understood the scenario, but the best way to avoid duplication is to use a Set structure such as HashSet
You could that by having a Map<String, List<Passenger>>.
Meaning: whenever you process a destination, you ask the map if it contains that destination. If yes, it already as a value which is a list; of not; you put a new List for that key, like:
Map<String, List<Passenger>> listsByDestination = new HashMap<>;
String destination = ... wherever
if (listsByDestination.contains(destination)) {
... already known
} else {
listsByDestination.put(destination, new ArrayList<>());
}
and so on.
Side not: I uppercased Passenger, because, well class names start UpperCase in Java.
Something like this might help you
Map<String, List<Passenger>> pasengerMaps = new HashMap();
if(pasengerMaps.contains("JFK")){
pasengerMaps.get("JFK").add(passenger)
}else{
pasengerMaps.put("JFK",new ArrayList<Passenger>());
}
I would use MultiMap from Google's guava library.
ListMultimap<String, Passenger> multimap = ArrayListMultimap.create();
multimap.put("destination",passenger1);
multimap.put("destination",passenger2);
You can retrive passenger list of some specific destination like this:
List<Passenger> passengerList = multimap.get("destination");

how to read a list of objects from the configuration file in play framework

How can i read a list of users from the configuration file in play framework?
i have tried doing something like this:
users=[{uid:123,pwd:xyz},{uid:321,pwd:abc}]
from the play application
List<Object> uids = Play.application().configuration().getList("users");
will give me this a list of objects, if I iterate through the list i get each object as
{uid=123,pwd=xyz} and {uid=321,pwd=abc}
at this point i don't know how i can elegantly get the value of the uid, i can do some hacky job as omit the first and last bracket and parse for the before after equal sign, but it would be too ugly! any idea? (the application is written in java)
thanks
A Scala implementation that avoids the deprecated getConfigList method would rely on retrieving a Seq[Configuration] as follows:
case class UserConfig(uid: Int, pwd: String)
val userConfigs: Seq[UserConfig] = configuration.get[Seq[Configuration]]("users").map { userConfig =>
UserConfig(userConfig.get[Int]("uid"), userConfig.get[String]("pwd"))
}
Since I had recently the same problem and this is still unanswered,
here is my suggestion:
List<User> users = getConfig().getConfigList("users").stream().map(
config -> new User(config.getString("uid"), config.getBoolean("pwd"))
).collect(Collectors.toList());
As far as I know there are no tuples or anything in Java, you need to use either an object or a list with two elements. I decided to go for an object here, you can also return a list.
A list of uid's sounds to me like:
# List of UID's
users=[123,456,789] // every number represents a UID
Then you can get this list as:
List<Object> uids = Play.application().configuration().getList("users");
And then do what you want with this:
for (Iterator<Object> iterator = uids.iterator(); iterator.hasNext();) {
Object object = (Object) iterator.next();
System.out.println(object);
}
Is this what you are looking for?
BTW, you can read more about Play Framework configuration options: http://www.playframework.com/documentation/2.1.0/Configuration

Categories