Compare value objects using a custom comparator - javers

I want to compare value objects in a way that null properties are ignored.
More specifically, I only want to include those properties of a value object in the comparison which are not-null on the right side.
E.g.
class Person {
String name;
String surname;
}
Person personLeft = new Person();
personLeft.name = "John";
personLeft.surname = "Doe";
Person personRight = new Person();
personRight.name="John"
// this should NOT yield any changes
javers.compare(personLeft, personRight);
// that comparison however, will show that surname has changed
javers.compare(personRight, personLeft);
I though I could tackle this problem by writing a custom comparator and registering it for Person.
Unfortunately this comparator is never called.
Stumbling upon that post, I fear that this is not possible using a custom comparator for the Person class.
Instead I would have to register custom comparators for all containing value types of the Person class, i.e. String.
Is that the intended use of javers or are there any alternatives to that approach?

What is important here is that CustomValueComparator can be used only for Value types. So you have 2 options:
Map Person as Value and then you implement diff algorithm for
Person. It works but is awkward because Person is more like an
Entity.
Register a CustomValueComparator for Strings (all Strings), and then you can use Person as Entity. That's the option that I would choose.
See how it works (groovy):
class Entity {
#Id int id
Person person
}
class Person {
String name
}
def "should use CustomValueComparator for Person when Person is mapped as Value"(){
given:
def javers = JaversBuilder.javers().registerValue(Person,
{ l, r -> if (r.name == null) return true
else return r.name.equals(l.name)
}).build()
def personLeft = new Person(name: "john")
def personRight = new Person()
def eLeft = new Entity(id:1, person: personLeft)
def eRight = new Entity(id:1, person: personRight)
expect:
javers.compare(eLeft, eRight).changes.size() == 0
javers.compare(eRight, eLeft).changes.size() == 1
javers.getTypeMapping(Person) instanceof ValueType
}
def "should used CustomValueComparator for Strings"(){
given:
def javers = JaversBuilder.javers().registerValue(String,
{ l, r -> if (r == null) return true
else return r.equals(l)
}).build()
def personLeft = new Person(name: "john")
def personRight = new Person()
expect:
javers.compare(personLeft, personRight).changes.size() == 0
javers.compare(personRight, personLeft).changes.size() == 1
javers.getTypeMapping(Person) instanceof ValueObjectType
}

Related

access content of parent's field in graphene python

I am using graphene in python.
Let's say I have the following schema:
extends type Query {
a(search:String):A
}
type A {
b:B
important_info:ID
}
type B {
fieldone: String
fieldtwo: String
}
Now I'd like to query:
query {
a(search:"search string") {
b {
fieldone
}
}
}
however fieldone is based on important_info.
My class B looks like this:
class B(graphene.ObjectType):
fieldone = graphene.String()
fieldtwo = graphene.String()
def resolve_fieldone(self,info):
# Here I want access to important_info, but I don't know how ...
return "something based on important_info"
How can I access important info from within the resolver of fieldone?
It seems there is no obvious or documented solution for this requirement.
I solved it by adding the root object to info.context within the outermost type:
class B(ObjectType):
c = String()
def resolve_c(parent, info):
return 'foo' if info.context['z'] == '' else 'bar'
class A(ObjectType):
b = Field(B)
def resolve_b(parent, info):
return parent.b
class Query(ObjectType):
a = Field(A)
z = String()
def resolve_a(parent, info):
return some_function_to_get_a()
def resolve_z(parent, info):
z = some_function_to_get_z()
info.context['z'] = z
return z

Replacing for loops for searching list in kotlin

I am trying to convert my code as clean as possible using the Kotlin's built-in functions. I have done some part of the code using for loops. But I want to know the efficient built-in functions to be used for this application
I have two array lists accounts and cards.
My goal is to search a specific card with the help of its card-number, in the array list named cards.
Then I have to validate the pin. If the pin is correct, by getting that gift card's customerId I have to search the account in the array list named accounts. Then I have to update the balance of the account.
These are the class which I have used
class Account{
constructor( )
var id : String = generateAccountNumber()
var name: String? = null
set(name) = if (name != null) field = name.toUpperCase() else { field = "Unknown User"; println("invalid details\nAccount is not Created");}
var balance : Double = 0.0
set(balance) = if (balance >= 0) field = balance else { field = 0.0 }
constructor(id: String = generateAccountNumber(), name: String?,balance: Double) {
this.id = id
this.balance = balance
this.name = name
}
}
class GiftCard {
constructor( )
var cardNumber : String = generateCardNumber()
var pin: String? = null
set(pin) = if (pin != null) field = pin else { field = "Unknown User"; println("Please set the pin\nCard is not Created");}
var customerId : String = ""
set(customerId) = if (customerId != "") field = customerId else { field = "" }
var cardBalance : Double = 0.0
set(cardBalance) = if (cardBalance > 0) field = cardBalance else { field = 0.0; println("Card is created with zero balance\nPlease deposit") }
var status = Status.ACTIVE
constructor(cardNumber: String = generateCardNumber(),
pin: String,
customerId: String,
cardBalance: Double = 0.0,
status: Status = Status.ACTIVE){
this.cardNumber = cardNumber
this.pin = pin
this.customerId = customerId
this.cardBalance = cardBalance
this.status = status
}
}
This is the part of code, I have to be changed :
override fun closeCard(cardNumber: String, pin: String): Pair<Boolean, Boolean> {
for (giftcard in giftcards) {
if (giftcard.cardNumber == cardNumber) {
if (giftcard.pin == pin) {
giftcard.status = Status.CLOSED
for (account in accounts)
account.balance = account.balance + giftcard.cardBalance
giftcard.cardBalance = 0.0
return Pair(true,true)
}
\\invalid pin
return Pair(true,false)
}
}
\\card is not present
return Pair(false,false)
}
Both classes are not very idiomatic. The primary constructor of a Kotlin class is implicit and does not need to be defined, however, you explicitly define a constructor and thus you add another one that is empty.
// good
class C
// bad
class C {
constructor()
}
Going further, Kotlin has named arguments and default values, so make use of them.
class Account(
val id: String = generateAccountNumber(),
val name: String = "Unknown User",
val balance: Double = 0.0
)
Double is a very bad choice for basically anything due to its shortcomings, see for instance https://www.floating-point-gui.de/ Choosing Int, Long, heck even BigDecimal would be better. It also seems that you don’t want the balance to ever go beneath zero, in that case consider UInt and ULong.
Last but not least is the mutability of your class. This can make sense but it also might be dangerous. It is up to you to decide upon your needs and requirements.
enum class Status {
CLOSED
}
#ExperimentalUnsignedTypes
class Account(private var _balance: UInt) {
val balance get() = _balance
operator fun plusAssign(other: UInt) {
_balance += other
}
}
#ExperimentalUnsignedTypes
class GiftCard(
val number: String,
val pin: String,
private var _status: Status,
private var _balance: UInt
) {
val status get() = _status
val balance get() = _balance
fun close() {
_status = Status.CLOSED
_balance = 0u
}
}
#ExperimentalUnsignedTypes
class Main(val accounts: List<Account>, val giftCards: List<GiftCard>) {
fun closeCard(cardNumber: String, pin: String) =
giftCards.find { it.number == cardNumber }?.let {
(it.pin == pin).andAlso {
accounts.forEach { a -> a += it.balance }
it.close()
}
}
}
inline fun Boolean.andAlso(action: () -> Unit): Boolean {
if (this) action()
return this
}
We change the return type from Pair<Boolean, Boolean> to a more idiomatic Boolean? where Null means that we did not find anything (literally the true meaning of Null), false that the PIN did not match, and true that the gift card was closed. We are not creating a pair anymore and thus avoid the additional object allocation.
The Boolean.andAlso() is a handy extension function that I generally keep handy, it is like Any.also() from Kotlin’s STD but only executes the action if the Boolean is actually true.
There's probably a million different ways to do this, but here's one that at least has some language features I feel are worthy to share:
fun closeCard(cardNumber: String, pin: String): Pair<Boolean, Boolean> {
val giftCard = giftcards.find { it.cardNumber == cardNumber }
?: return Pair(false, false)
return if (giftCard.pin == pin) {
giftCard.status = Status.CLOSED
accounts.forEach {
it.balance += giftCard.cardBalance
}
Pair(true, true)
} else
Pair(true, false)
}
The first thing to notice if the Elvis operator - ?: - which evaluates the right side of the expression if the left side is null. In this case, if find returns null, which is equivalent to not finding a card number that matches the desired one, we'll immediately return Pair(false, false). This is the last step in your code.
From there one it's pretty straight forward. If the pins match, you loop through the accounts list with a forEach and close the card. If the pins don't match, then we'll go straight to the else branch. In kotlin, if can be used as an expression, therefore we can simply put the return statement before the if and let it return the result of the last expression on each branch.
PS: I won't say this is more efficient than your way. It's just one way that uses built-in functions - find and forEach - like you asked, as well as other language features.
PPS: I would highly recommend to try and find another way to update the lists without mutating the objects. I don't know your use cases, but this doesn't feel too thread-safe. I didn't post any solution for this, because it's outside the scope of this question.

Conditional method call in the map method java 8

Persons = personDao.getFileInformation(filePath)
.skip(1)
.map(this::getPerson)
.filter(person -> person != null)
.collect(Collectors.toList());
getFileInformation(filePath) returns Stream<String>
after reading lines in a file.
I would like to replace the getPerson method with a getMale or getFemale method based on the value of an enum
public enum gender {
male,female
}
How can this be achieved used lambda expressions?
If you just want to filter by gender (assuming there is an accessor like Person.getGender), then you only need to add a filter:
List<Person> malePeople;
malePeople = personDao.getFileInformation(filePath)
.skip(1)
.map(this::getPerson)
.filter(Objects::nonNull)
.filter(p -> p.getGender() == gender.male) // or gender.female
.collect(Collectors.toList());
If you rather want to group your results, the following will help you:
Map<gender, List<Person>> peopleByGender;
peopleByGender = personDao.getFileInformation(filePath)
.skip(1)
.map(this::getPerson)
.filter(Objects::nonNull)
.collect(Collectors.groupingBy(Person::getGender));
now access all your female people with:
List<Person> femalePeople = peopleByGender.get(gender.female);
and the male ones with:
List<Person> malePeople = peopleByGender.get(gender.male);
If you just wanted to use a method to simplify the filter-predicate (p -> p.getGender() == gender.male), then you could use one of the following:
.filter(this::getMale) // or: YourClass::getMale for a static method
where this::getMale refers to the following method:
boolean getMale(Person p) {
return p.getGender() == gender.male;
}
or
.filter(getMale())
where getMale() refers to the following method:
Predicate<Person> getMale() {
return p -> p.getGender() == gender.male;
}

Linq join two lists: is it more efficient to use Dictionary?

Final rephrase
Below I join two sequences and I wondered if it would be faster to create a Dictionary of one sequence with the keySelector of the join as key and iterate through the other collection and find the key in the dictionary.
This only works if the key selector is unique. A real join has no problem with two records having the same key. In a dictionary you'll have to have unique keys
I measured the difference, and I noticed that the dictionary method is about 13% faster. In most use cases ignorable. See my answer to this question
Rephrased question
Some suggested that this question is the same question as LINQ - Using where or join - Performance difference?, but this one is not about using where or join, but about using a Dictionary to perform the join.
My question is: if I want to join two sequences based on a key selector, which method would be faster?
Put all items of one sequence in a Dictionary and enumerate the other sequence to see if the item is in the Dictionary. This would mean to iterate through both sequences once and calculate hash codes on the keySelector for every item in both sequences once.
The other method: use System.Enumerable.Join.
The question is: Would Enumerable.Join for each element in the first list iterate through the elements in the second list to find a match according to the key selector, having to compare N * N elements (is this called second order?) or would it use a more advanced method?
Original question with examples
I have two classes, both with a property Reference. I have two sequences of these classes and I want to join them based on equal Reference.
Class ClassA
{
public string Reference {get;}
...
}
public ClassB
{
public string Reference {get;}
...
}
var listA = new List<ClassA>()
{
new ClassA() {Reference = 1, ...},
new ClassA() {Reference = 2, ...},
new ClassA() {Reference = 3, ...},
new ClassA() {Reference = 4, ...},
}
var listB = new List<ClassB>()
{
new ClassB() {Reference = 1, ...},
new ClassB() {Reference = 3, ...},
new ClassB() {Reference = 5, ...},
new ClassB() {Reference = 7, ...},
}
After the join I want combinations of ClassA objects and ClassB objects that have an equal Reference. This is quite simple to do:
var myJoin = listA.Join(listB, // join listA and listB
a => a.Reference, // from listA take Reference
b => b.Reference, // from listB take Reference
(objectA, objectB) => // if references equal
new {A = objectA, B = objectB}); // return combination
I'm not sure how this works, but I can imagine that for each a in listA the listB is iterated to see if there is a b in listB with the same reference as A.
Question: if I know that the references are Distinct wouldn't it be more efficient to convert B into a Dictionary and compare the Reference for each element in listA:
var dictB = listB.ToDictionary<string, ClassB>()
var myJoin = listA
.Where(a => dictB.ContainsKey(a.Reference))
.Select(a => new (A = a, B = dictB[a.Reference]);
This way, every element of listB has to be accessed once to put in the dictionary and every element of listA has to be accessed once, and the hascode of Reference has to be calculated once.
Would this method be faster for large collections?
I created a test program for this and measured the time it took.
Suppose I have a class of Person, each person has a name and a Father property which is of type Person. If the Father is not know, the Father property is null
I have a sequence of Bastards (no father) that have exactly one Son and One Daughter. All Daughters are put in one sequence. All sons are put in another sequences.
The query: join the sons and the daughters that have the same father.
Results: Joining 1 million families using Enumerable.Join took 1.169 sec. Joining them using Dictionary join used 1.024 sec. Ever so slightly faster.
The code:
class Person : IEquatable<Person>
{
public string Name { get; set; }
public Person Father { get; set; }
// + a lot of equality functions get hash code etc
// for those interested: see the bottom
}
const int nrOfBastards = 1000000; // one million
var bastards = Enumerable.Range (0, nrOfBastards)
.Select(i => new Person()
{ Name = 'B' + i.ToString(), Father = null })
.ToList();
var sons = bastards.Select(father => new Person()
{Name = "Son of " + father.Name, Father = father})
.ToList();
var daughters = bastards.Select(father => new Person()
{Name = "Daughter of " + father.Name, Father = father})
.ToList();
// join on same parent: Traditionally and using Dictionary
var stopwatch = Stopwatch.StartNew();
this.TraditionalJoin(sons, daughters);
var time = stopwatch.Elapsed;
Console.WriteLine("Traditional join of {0} sons and daughters took {1:F3} sec", nrOfBastards, time.TotalSeconds);
stopwatch.Restart();
this.DictionaryJoin(sons, daughters);
time = stopwatch.Elapsed;
Console.WriteLine("Dictionary join of {0} sons and daughters took {1:F3} sec", nrOfBastards, time.TotalSeconds);
}
private void TraditionalJoin(IEnumerable<Person> boys, IEnumerable<Person> girls)
{ // join on same parent
var family = boys
.Join(girls,
boy => boy.Father,
girl => girl.Father,
(boy, girl) => new { Son = boy.Name, Daughter = girl.Name })
.ToList();
}
private void DictionaryJoin(IEnumerable<Person> sons, IEnumerable<Person> daughters)
{
var sonsDictionary = sons.ToDictionary(son => son.Father);
var family = daughters
.Where(daughter => sonsDictionary.ContainsKey(daughter.Father))
.Select(daughter => new { Son = sonsDictionary[daughter.Father], Daughter = daughter })
.ToList();
}
For those interested in the equality of Persons, needed for a proper dictionary:
class Person : IEquatable<Person>
{
public string Name { get; set; }
public Person Father { get; set; }
public bool Equals(Person other)
{
if (other == null)
return false;
else if (Object.ReferenceEquals(this, other))
return true;
else if (this.GetType() != other.GetType())
return false;
else
return String.Equals(this.Name, other.Name, StringComparison.OrdinalIgnoreCase);
}
public override bool Equals(object obj)
{
return this.Equals(obj as Person);
}
public override int GetHashCode()
{
const int prime1 = 899811277;
const int prime2 = 472883293;
int hash = prime1;
unchecked
{
hash = hash * prime2 + this.Name.GetHashCode();
if (this.Father != null)
{
hash = hash * prime2 + this.Father.GetHashCode();
}
}
return hash;
}
public override string ToString()
{
return this.Name;
}
public static bool operator==(Person x, Person y)
{
if (Object.ReferenceEquals(x, null))
return Object.ReferenceEquals(y, null);
else
return x.Equals(y);
}
public static bool operator!=(Person x, Person y)
{
return !(x==y);
}
}

Linq "reporting" question with list properties

I have an entity object that contains a list property. I'd like to expand the list values to the right. Being new to LINQ, I'm not sure how to do this. I could strongly type an object, but then I'd have to know the count/values at compile time and I'd like to make it more dynamic.
The output that I'm wanting is something like:
Name Demo1 Demo2 Demo3
Person Name1 TX TX
Person Name2 TX OK
Person Name3 TX TX OK
Main Class
public Main()
{
List<Event> events = new List<Event>();
events.Add(new Event()
{
EventDate = DateTime.Now,
EventLocation = new Location() { State = "TX" },
EventName = "Demo1"
});
events.Add(new Event()
{
EventDate = DateTime.Now,
EventLocation = events[0].EventLocation,
EventName = "Demo2"
});
events.Add(new Event()
{
EventDate = DateTime.Now,
EventLocation = new Location() { State = "OK" },
EventName = "Demo3"
});
List<Person> people = new List<Person>();
Person person1 = new Person();
person1.Name = "Person Name1";
person1.Events.Add(events[0]);
person1.Events.Add(events[1]);
Person person2 = new Person();
person2.Name = "Person Name2";
person2.Events.Add(events[0]);
person2.Events.Add(events[2]);
Person person3 = new Person();
person3.Name = "Person Name3";
person3.Events.Add(events[0]);
person3.Events.Add(events[1]);
person3.Events.Add(events[2]);
people.Add(person1);
people.Add(person2);
people.Add(person3);
}
It depends on whether you want to run the query in memory or in databse. In any case, you'll need to return a list with the "dynamic" part of the results, because you cannot dynamically generate members of anonymous types (and working with them would be difficult).
In memory (as in your example), you can write the following query:
// Find names of all events (for all people)
var allNames =
(from p in people
from e in p.Events
select e.EventName).Distinct();
// Find events for every person
var res =
from p in people
let known = p.Events.ToDictionary(e => e.EventName)
select new {
p.Name,
Events = allNames.Select(n =>
known.ContainsKey(n)?known[n].EventLocation:"N/A")
};
The first query gets names of all events (we use it later to find a value for all event for every person). The second query iterates over all people. It first creates dictionary with events (for fast lookup in memory) and then iterates over all event names and tries to find them in the dictionary (returning "N/A" if it is not found).

Resources