In my unit test, I need to test order of elements as that :
test("Check map order", () {
LinkedHashMap<String, String> actualMap = LinkedHashMap();
actualMap["0"] = "firstValue";
actualMap["1"] = "secondValue";
LinkedHashMap<String, String> expectedMap = LinkedHashMap();
expectedMap["1"] = "secondValue";
expectedMap["0"] = "firstValue";
print("actual: $actualMap");
print("expected: $expectedMap");
expect(actualMap, isNot(expectedMap));
});
This test fails, event if order is respected:
actual: {0: firstValue, 1: secondValue}
expected: {1: secondValue, 0: firstValue}
package:test_api expect
test/services/game/negotiation/NegotiationGameService_test.dart 33:7 main.<fn>.<fn>
Expected: not {'1': 'secondValue', '0': 'firstValue'}
Actual: {'0': 'firstValue', '1': 'secondValue'}
First idea that works but is a bit boring:
test("Check map order", () {
LinkedHashMap<String, String> actualMap = LinkedHashMap();
actualMap["0"] = "firstValue";
actualMap["1"] = "secondValue";
LinkedHashMap<String, String> expectedMapSameOrder = LinkedHashMap();
expectedMap["0"] = "firstValue";
expectedMap["1"] = "secondValue";
LinkedHashMap<String, String> expectedMapDifferentOrder = LinkedHashMap();
expectedMap["1"] = "secondValue";
expectedMap["0"] = "firstValue";
print("actual: $actualMap");
print("expected: $expectedMapSameOrder");
print("expected: $expectedMapDifferentOrder");
expect(actualMap, expectedMapSameOrder);
expect(actualMap.keys, isNot(orderedEquals(expectedMapSameOrder.keys)));
expect(actualMap, expectedMapDifferentOrder);
expect(actualMap.keys, orderedEquals(expectedMapDifferentOrder.keys));
});
Related
I added an Int attribute in my class named isAlsoActor but it doesn't get saved in DynamoDB. Here is the class I'm trying to save in Dynamo:
package me.brunosantana.dto
import com.fasterxml.jackson.annotation.JsonInclude
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbAttribute
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbIgnore
import software.amazon.awssdk.services.dynamodb.model.AttributeValue
private const val TYPE = "ARTIST"
#DynamoDbBean
//#JsonInclude(JsonInclude.Include.NON_EMPTY)
data class Artist(
#get:DynamoDbAttribute("ArtistName")
var name: String,
#get:DynamoDbAttribute("Nationality")
var nationality: String,
#get:DynamoDbAttribute(value = "IsAwardWinner")
var isAwardWinner: Boolean,
#get:DynamoDbAttribute(value = "IsAlsoActor")
var isAlsoActor: Int,
#get:DynamoDbIgnore
val songs: MutableList<Song> = mutableListOf()
): DynamoBaseModel(
pkType = "artist",
pkId = name.lowercase().replace(" ", "_"),
sk = "artist#${name.lowercase().replace(" ", "_")}",
gsi1pk = "type#artist",
gsi1sk = "type#artist",
) {
constructor(
name: String,
nationality: String,
isAwardWinner: Boolean,
isAlsoActor: Int
) :
this(
name = name,
nationality = nationality,
isAwardWinner = isAwardWinner,
isAlsoActor = isAlsoActor,
songs = mutableListOf()
)
#Deprecated(message = "Intended to be used only by AWS SDK")
constructor() :
this(
name = "",
nationality = "",
isAwardWinner = false,
isAlsoActor = 0,
songs = mutableListOf()
)
#DynamoDbAttribute("Type")
fun getType(): String {
return TYPE
}
fun setType(type: String) {
// Do nothing, this setter is just to make the AWS SDK 2.x happy
}
fun addAllSongs(songs: MutableList<Song>){
this.songs.addAll(songs)
}
companion object {
fun attributeMapToArtist(attributeMap: Map<String, AttributeValue>): Artist {
val name = attributeMap["ArtistName"]!!.s()
val nationality = attributeMap["Nationality"]!!.s()
val isAwardWinner = attributeMap["IsAwardWinner"]?.bool() ?: false
val isAlsoActor = attributeMap["IsAlsoActor"]?.n()?.toInt() ?: 0
val versionTimestamp = attributeMap["VersionTimestamp"]?.s()
val artist = Artist(
name = name,
nationality = nationality,
isAwardWinner = isAwardWinner,
isAlsoActor = isAlsoActor)
artist.versionTimestamp = versionTimestamp
return artist
}
}
}
Here is the code responsible for saving it in Dynamo (it's using putItem):
fun saveModel(model: DynamoBaseModel){
val pk = "${model.pkType}#${model.pkId}"
val existingModel = findByPkAndSk(pk, model.sk)
val existingVersion = existingModel?.versionTimestamp
val incomingVersion = model.versionTimestamp!!
try {
when(model){
is Artist -> {
save(model, incomingVersion, existingVersion, true)
}
is Song -> {
save(model, incomingVersion, existingVersion, true)
}
}
}catch (e: DynamoDbException){
e.printStackTrace()
}
}
fun findByPkAndSk(pk: String, sk: String): DynamoBaseModel? {
val tableName = "music"
val pkAttribute = AttributeValue.builder().s(pk).build()
val skAttribute = AttributeValue.builder().s(sk).build()
val queryReq = QueryRequest.builder()
.tableName(tableName)
.consistentRead(false)
.keyConditionExpression("pk = :pk and sk = :sk")
.expressionAttributeValues(mapOf(":pk" to pkAttribute, ":sk" to skAttribute))
.build()
try {
val queryResponse: QueryResponse = client.query(queryReq)
queryResponse.items().firstOrNull {
return when(it["Type"]!!.s()) {
"ARTIST" -> Artist.attributeMapToArtist(it)
"SONG" -> Song.attributeMapToSong(it)
else -> throw Exception("Not found")
}
}
} catch (e: DynamoDbException) {
System.err.println(e.message)
}
return null
}
private final inline fun <reified T> save(model: T, incomingVersion: String, existingVersion: String?, versioningCheck: Boolean){
println("incoming: $incomingVersion existing: $existingVersion")
val musicTable: DynamoDbTable<T> =
enhancedClient.table("music", TableSchema.fromBean(T::class.java))
if(versioningCheck){
if(existingVersion == null){
println("no existing version")
musicTable.putItem(model)
}else{
val incomingDate = DateUtils.convertStringToZonedDateTime(incomingVersion)
val existingDate = DateUtils.convertStringToZonedDateTime(existingVersion)
if(DateUtils.isIncomingDateNewer(incomingDate, existingDate)){
println("override")
musicTable.putItem(model) //check how to override properly
}else{
println("Skip. $incomingVersion is older than $existingVersion")
}
}
}else{
println("check disabled")
musicTable.putItem(model)
}
}
Does anyone have any idea why it's not saving the Int attribute? It saves the item in the table, but the Int attribute does not appear there.
Thank you.
I need to return all list items, in forEach it works fine, outside the loop it only returns the last item.
fun scanAndConvertFile(): String {
val scanner = Scanner(System.`in`)
print("Enter path to file to convert: ")
val fileName: String = scanner.nextLine()
val bufferedReader: BufferedReader = File(fileName).bufferedReader()
var result = bufferedReader.use { it.readText() }
val header = result.substring(0, result.indexOf(":61:"))
val body = result.substring(result.indexOf(":61:"), result.lastIndexOf(":61:220131C6"))
val footer = result.substring(result.lastIndexOf(":61:220131C6"), result.length)
var list = body.split(":61:")
list = list.filter { it.isNotEmpty() }
list = list.map {
":61:$it"
}
list.forEach() {
val part1 = it.substring(0, it.indexOf("?20"))
var part2ToBePasted = it.substring(it.indexOf("?20"), it.indexOf("?00"))
part2ToBePasted = part2ToBePasted.drop(3)
val part3 = it.substring(it.indexOf("?00"), it.indexOf("?27"))
var part4ToPast = it.substring(it.indexOf("?27"), it.indexOf("?28"))
part4ToPast = part4ToPast.drop(3)
val part5 = it.substring(it.indexOf("?28"), it.length)
list = if(part4ToPast.equals("")) {
listOf(part1.plus("?20").plus(part2ToBePasted).plus(part3).plus("?27").plus(part4ToPast).plus(part5))
} else {
listOf(part1.plus("?20").plus(part4ToPast).plus(part3).plus("?27").plus(part4ToPast).plus(part5))
}
// println(list) - works good
}
val converted = header.plus(list).plus(footer)
// println(converted) - print only last element of list
return converted
}
I tried to clean up your code a little (with no guarantee of course since I do not have any test data):
fun scanAndConvertFile(): String {
print("Enter path to file to convert: ")
val fileName: String = Scanner(System.`in`).nextLine()
val bufferedReader: BufferedReader = File(fileName).bufferedReader()
val result = bufferedReader.use { it.readText() }
val header = result.substring(0, result.indexOf(":61:"))
val footer = result.substring(result.lastIndexOf(":61:220131C6"), result.length)
val list = result
.substring(result.indexOf(":61:"), result.lastIndexOf(":61:220131C6"))
.split(":61:")
.filter { it.isNotEmpty() }
.map { ":61:$it" }
.map {
val indexOf00 = it.indexOf("?00")
val indexOf20 = it.indexOf("?20")
val indexOf27 = it.indexOf("?27")
val indexOf28 = it.indexOf("?28")
val substring27to28 = it.substring(indexOf27, indexOf28).drop(3)
it.substring(0, indexOf20)
.plus("?20")
.plus(if (substring27to28 == "") it.substring(indexOf20, indexOf00).drop(3) else substring27to28)
.plus(it.substring(indexOf00, indexOf27))
.plus("?27")
.plus(substring27to28)
.plus(it.substring(indexOf28, it.length))
}
return header.plus(list).plus(footer)
}
Basically you need to use map instead of forEach to return a list. map is used to transform each element of a list, while with forEach you do something to or with each element, but no list is returned.
How to fetch the HashMap based on Max-key field
Eaxmple:-
List<Map<String, Integer>> data = new ArrayList<Map<String, Integer>>();
Map<String, Integer> map1 = new HashMap<>();
map1.put("A", 10);
map1.put("B", 15);
map1.put("C", 20);
Map<String, Integer> map2 = new HashMap<>();
map2.put("A", 20);
map2.put("B", 30);
map2.put("C", 50);
Map<String, Integer> map3 = new HashMap<>();
map3.put("A", 50);
map3.put("B", 60);
map3.put("C", 70);
data.add(map1);
data.add(map2);
data.add(map3);
Here I have 3 maps that I'm storing in the List.
Now I want to filter a map based on max A key value.
In the above map3 A value has the max integer value.
Expected out is:-
In the last only the map3 should present inside the List.
Is it possible to filter using java8?
Any suggestions would be helpful
I finally able to do this with help of comparator
Here is the code that will filter based filtering based on max date:-
Result is stored in the firstMap variable...
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String args[]) throws ParseException {
Map<String, String> s = test();
System.err.println(s.toString());
}
public static Map<String, String> test() throws ParseException {
List<Map<String, String>> data = new ArrayList<Map<String, String>>();
Map<String, String> map1 = new HashMap<>();
map1.put("A", "2021-03-08");
Map<String, String> map2 = new HashMap<>();
map2.put("A", "2021-03-23");
Map<String, String> map3 = new HashMap<>();
map3.put("A", "2021-03-21");
data.add(map1);
data.add(map2);
data.add(map3);
SimpleDateFormat si = new SimpleDateFormat("yyyy-MM-dd");
Date firstMax = si.parse(data.get(0).get("A"));
Map<String, String> firstMap = data.get(0);
for (Map<String, String> map : data) {
Date loopMax = si.parse(map.get("A"));
if (firstMax.compareTo(loopMax) < 0) {
firstMax = loopMax;
firstMap = map;
}
}
return firstMap;
}
}
Output:-
{A=2021-03-23}
I have the following list of maps:
[
{
"id":1,
"asset_id":"name1",
"asset_price":100.00,
"asset_date":"09-09-09"
},
{
"id":2,
"asset_id":"name2",
"asset_price":50.00,
"asset_date":"10-09-09"
},
{
"id":3,
"asset_id":"name1",
"asset_price":100.00,
"asset_date":"11-09-09"
}
]
How can I produce a new list that combines duplicate asset_id and sums the price as below:
[
{
"id":1,
"asset_id":"name1",
"asset_price":200.00,
"asset_date":"09-09-09"
},
{
"id":2,
"asset_id":"name2",
"asset_price":50.00,
"asset_date":"10-09-09"
}
]
Class
int id;
String assetId;
String assetName;
String assetSymbol;
String assetImage;
double assetAmount;
String assetCurrency;
double assetPrice;
String assetDate;
Asset(
{this.id,
this.assetId,
this.assetName,
this.assetSymbol,
this.assetImage,
this.assetAmount,
this.assetCurrency,
this.assetPrice,
this.assetDate});
Map<String, dynamic> toMapWithoutId() {
final map = new Map<String, dynamic>();
map["id"] = id;
map["asset_id"] = assetId;
map["asset_name"] = assetName;
map["asset_symbol"] = assetSymbol;
map["asset_image"] = assetImage;
map["asset_amount"] = assetAmount;
map["asset_currency"] = assetCurrency;
map["asset_price"] = assetPrice;
map["asset_date"] = assetDate;
return map;
}
Map<String, dynamic> toMap() {
final map = new Map<String, dynamic>();
map["id"] = id;
map["asset_id"] = assetId;
map["asset_name"] = assetName;
map["asset_symbol"] = assetSymbol;
map["asset_image"] = assetImage;
map["asset_amount"] = assetAmount;
map["asset_currency"] = assetCurrency;
map["asset_price"] = assetPrice;
map["asset_date"] = assetDate;
return map;
}
//to be used when converting the row into object
factory Asset.fromMap(Map<String, dynamic> data) => new Asset(
id: data["id"],
assetId: data["asset_id"],
assetName: data["asset_name"],
assetSymbol: data["asset_symbol"],
assetImage: data["asset_image"],
assetAmount: data["asset_amount"],
assetCurrency: data["asset_currency"],
assetPrice: data["asset_price"],
assetDate: data["asset_date"]);
}
<Team Side="Home" TeamRef="ref123">
<Goal PlayerRef="p1111" Time="10" >
<Assist PlayerRef="p9999">p9999</Assist>
</Goal>
<Goal PlayerRef="p4444" Time="11" >
<Assist PlayerRef="p9999">p9999</Assist>
</Goal>
<Goal PlayerRef="p7777 Time="13" >
<Assist PlayerRef="p9999">p9999</Assist>
</Goal>
<Goal PlayerRef="p7777 Time="17" >
<Assist PlayerRef="p9999">p9999</Assist>
</Goal>
</Team>
public void GetScorer(string side, string OCompetition, string OSeason, string OGameId)
{
try
{
var xDoc = XDocument.Load(test);
var query = from q in xDoc.Descendants("Team")
where (string)q.Attribute("Side") == side
from d in q.Elements("Goal")
select new
{
TeamRef = q.Attribute("TeamRef").Value,
PlayerRef = d.Attribute("PlayerRef").Value,
Time = d.Attribute("Time").Value
};
var count = 0;
foreach (var qq in query)
{
if (side == "Home")
{
if (HomeSlateScorerList[count].PlayerRef != qq.PlayerRef)
{
HomeSlateScorerList.Add(new Scorer() { PlayerRef = qq.PlayerRef, Time = qq.Time, LastName = GetPlayerNameSlate(qq.PlayerRef, OSeason, OCompetition, OGameId) });
}
else
{
HomeSlateScorerList[count].Time = HomeSlateScorerList[count].Time + "' ";
}
}
if (side == "Away")
{
AwaySlateScorerList.Add(new Scorer() { PlayerRef = qq.PlayerRef, Time = qq.Time, LastName = GetPlayerNameSlate(qq.PlayerRef, OCompetition, OSeason, OGameId) });
}
count++;
}
}
catch (Exception)
{
// ignored
}
}
I would like to edit a player in a list of players
HomeSlateScorerList = new List<Scorer>();
AwaySlateScorerList = new List<Scorer>();
what I would like to achieve is for e.g. there are two players with the ref of "p7777" so in the list of object I would like to have one player with the playerref of "p7777" so if the player exist the format will be
playerref = "p7777"
Time = 13' 17'
or if one player its
Time = 13'
or if another goal is added to the xml its
Time = 13' 17' 25'
HomeSlateScorerList = HomeSlateScorerList
.GroupBy(s => s.PlayerRef)
.Select(g => new Scorer { PlayerRef = g.Key, Time = string.Join(", ", g.Select(v => v.Time)) })
.ToList();
Thanks to: #SergeyS SergeyS