Can a class that tracks time be immutable? - oop

Let's say I have a simple class in Java that stores a time stamp:
public final class Timestamp {
private final long value;
public Timestamp(final long value) {
this.value = value;
}
public long getValue() {
return value;
}
}
That's immutable. But what if instead of getValue() I write a method called getProgress()?
public final class Timestamp {
private final long value;
public Timestamp(final long value) {
this.value = value;
}
public float getProgress() {
return (SomeExternalPlace.getTimestamp() - value) / SomeFloatConstant;
}
}
The object's state never changes, but the value from getProgress() does change over time.
Is the latter class considered immutable? Why or why not?

It is immutable, because its state (the value field) cannot change once an instance of Timestamp has been created. The timestamp represents a certain point in time, and that cannot be changed.
Data returned from the methods doesn't necessarily need to be always the same.
Additionally, Timestamp exhibits all the properties you'd expect from an immutable object (e.g., thread-safety).
Here's another "weird" example of immutability:
class LazyList<T>
{
private readonly T _head;
private LazyList<T> _tail;
private readonly Func<LazyList<T>> _tailDelegate;
private bool _created;
public LazyList(T head, Func<LazyList<T>> tailDelegate)
{
_head = head;
_tailDelegate = tailDelegate;
_created = false;
}
public T GetHead()
{
return _head;
}
public LazyList<T> GetTail()
{
if(! _created)
{
_tail = _tailDelegate();
_created = true;
}
return _tail;
}
}
As you can see, the _tail isn't really immutable - it's null when LazyList<T> is instantiated, and is assigned only when the client calls GetTail(). But that really doesn't matter. Once the tail is created, it doesn't change; and before that, the tail still "exists", it just hasn't been realized yet.
This is actually how Scala's immutable Streams are implemented.

Related

HTTP end point property string starts with "is" will get omit [duplicate]

This might be a duplicate. But I cannot find a solution to my Problem.
I have a class
public class MyResponse implements Serializable {
private boolean isSuccess;
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
Getters and setters are generated by Eclipse.
In another class, I set the value to true, and write it as a JSON string.
System.out.println(new ObjectMapper().writeValueAsString(myResponse));
In JSON, the key is coming as {"success": true}.
I want the key as isSuccess itself. Is Jackson using the setter method while serializing? How do I make the key the field name itself?
This is a slightly late answer, but may be useful for anyone else coming to this page.
A simple solution to changing the name that Jackson will use for when serializing to JSON is to use the #JsonProperty annotation, so your example would become:
public class MyResponse implements Serializable {
private boolean isSuccess;
#JsonProperty(value="isSuccess")
public boolean isSuccess() {
return isSuccess;
}
public void setSuccess(boolean isSuccess) {
this.isSuccess = isSuccess;
}
}
This would then be serialised to JSON as {"isSuccess":true}, but has the advantage of not having to modify your getter method name.
Note that in this case you could also write the annotation as #JsonProperty("isSuccess") as it only has the single value element
I recently ran into this issue and this is what I found. Jackson will inspect any class that you pass to it for getters and setters, and use those methods for serialization and deserialization. What follows "get", "is" and "set" in those methods will be used as the key for the JSON field ("isValid" for getIsValid and setIsValid).
public class JacksonExample {
private boolean isValid = false;
public boolean getIsValid() {
return isValid;
}
public void setIsValid(boolean isValid) {
this.isValid = isValid;
}
}
Similarly "isSuccess" will become "success", unless renamed to "isIsSuccess" or "getIsSuccess"
Read more here: http://www.citrine.io/blog/2015/5/20/jackson-json-processor
Using both annotations below, forces the output JSON to include is_xxx:
#get:JsonProperty("is_something")
#param:JsonProperty("is_something")
When you are using Kotlin and data classes:
data class Dto(
#get:JsonProperty("isSuccess") val isSuccess: Boolean
)
You might need to add #param:JsonProperty("isSuccess") if you are going to deserialize JSON as well.
EDIT: If you are using swagger-annotations to generate documentation, the property will be marked as readOnly when using #get:JsonProperty. In order to solve this, you can do:
#JsonAutoDetect(isGetterVisibility = JsonAutoDetect.Visibility.NONE)
data class Dto(
#field:JsonProperty(value = "isSuccess") val isSuccess: Boolean
)
You can configure your ObjectMapper as follows:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
&& method.getName().startsWith("is")) {
return method.getName();
}
return super.nameForGetterMethod(config, method, defaultName);
}
});
I didn't want to mess with some custom naming strategies, nor re-creating some accessors.
The less code, the happier I am.
This did the trick for us :
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
#JsonIgnoreProperties({"success", "deleted"}) // <- Prevents serialization duplicates
public class MyResponse {
private String id;
private #JsonProperty("isSuccess") boolean isSuccess; // <- Forces field name
private #JsonProperty("isDeleted") boolean isDeleted;
}
Building upon Utkarsh's answer..
Getter names minus get/is is used as the JSON name.
public class Example{
private String radcliffe;
public getHarryPotter(){
return radcliffe;
}
}
is stored as { "harryPotter" : "whateverYouGaveHere" }
For Deserialization, Jackson checks against both the setter and the field name.
For the Json String { "word1" : "example" }, both the below are valid.
public class Example{
private String word1;
public setword2( String pqr){
this.word1 = pqr;
}
}
public class Example2{
private String word2;
public setWord1(String pqr){
this.word2 = pqr ;
}
}
A more interesting question is which order Jackson considers for deserialization. If i try to deserialize { "word1" : "myName" } with
public class Example3{
private String word1;
private String word2;
public setWord1( String parameter){
this.word2 = parameter ;
}
}
I did not test the above case, but it would be interesting to see the values of word1 & word2 ...
Note: I used drastically different names to emphasize which fields are required to be same.
You can change primitive boolean to java.lang.Boolean (+ use #JsonPropery)
#JsonProperty("isA")
private Boolean isA = false;
public Boolean getA() {
return this.isA;
}
public void setA(Boolean a) {
this.isA = a;
}
Worked excellent for me.
If you are interested in handling 3rd party classes not under your control (like #edmundpie mentioned in a comment) then you add Mixin classes to your ObjectMapper where the property/field names should match the ones from your 3rd party class:
public class MyStack32270422 {
public static void main(String[] args) {
ObjectMapper om3rdParty = new ObjectMapper();
om3rdParty .addMixIn(My3rdPartyResponse.class, MixinMyResponse.class);
// add further mixins if required
String jsonString = om3rdParty.writeValueAsString(new My3rdPartyResponse());
System.out.println(jsonString);
}
}
class MixinMyResponse {
// add all jackson annotations here you want to be used when handling My3rdPartyResponse classes
#JsonProperty("isSuccess")
private boolean isSuccess;
}
class My3rdPartyResponse{
private boolean isSuccess = true;
// getter and setter here if desired
}
Basically you add all your Jackson annotations to your Mixin classes as if you would own the class. In my opinion quite a nice solution as you don't have to mess around with checking method names starting with "is.." and so on.
there is another method for this problem.
just define a new sub-class extends PropertyNamingStrategy and pass it to ObjectMapper instance.
here is a code snippet may be help more:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
String input = defaultName;
if(method.getName().startsWith("is")){
input = method.getName();
}
//copy from LowerCaseWithUnderscoresStrategy
if (input == null) return input; // garbage in, garbage out
int length = input.length();
StringBuilder result = new StringBuilder(length * 2);
int resultLength = 0;
boolean wasPrevTranslated = false;
for (int i = 0; i < length; i++)
{
char c = input.charAt(i);
if (i > 0 || c != '_') // skip first starting underscore
{
if (Character.isUpperCase(c))
{
if (!wasPrevTranslated && resultLength > 0 && result.charAt(resultLength - 1) != '_')
{
result.append('_');
resultLength++;
}
c = Character.toLowerCase(c);
wasPrevTranslated = true;
}
else
{
wasPrevTranslated = false;
}
result.append(c);
resultLength++;
}
}
return resultLength > 0 ? result.toString() : input;
}
});
The accepted answer won't work for my case.
In my case, the class is not owned by me. The problematic class comes from 3rd party dependencies, so I can't just add #JsonProperty annotation in it.
To solve it, inspired by #burak answer above, I created a custom PropertyNamingStrategy as follow:
mapper.setPropertyNamingStrategy(new PropertyNamingStrategy() {
#Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if (method.getParameterCount() == 1 &&
(method.getRawParameterType(0) == Boolean.class || method.getRawParameterType(0) == boolean.class) &&
method.getName().startsWith("set")) {
Class<?> containingClass = method.getDeclaringClass();
String potentialFieldName = "is" + method.getName().substring(3);
try {
containingClass.getDeclaredField(potentialFieldName);
return potentialFieldName;
} catch (NoSuchFieldException e) {
// do nothing and fall through
}
}
return super.nameForSetterMethod(config, method, defaultName);
}
#Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName)
{
if(method.hasReturnType() && (method.getRawReturnType() == Boolean.class || method.getRawReturnType() == boolean.class)
&& method.getName().startsWith("is")) {
Class<?> containingClass = method.getDeclaringClass();
String potentialFieldName = method.getName();
try {
containingClass.getDeclaredField(potentialFieldName);
return potentialFieldName;
} catch (NoSuchFieldException e) {
// do nothing and fall through
}
}
return super.nameForGetterMethod(config, method, defaultName);
}
});
Basically what this does is, before serializing and deserializing, it checks in the target/source class which property name is present in the class, whether it is isEnabled or enabled property.
Based on that, the mapper will serialize and deserialize to the property name that is exist.

When to use parameter vs. when to use member variable in Kotlin?

Are there any indicators to deciding whether to use a parameter or member variable?
See below example:
open class BankAccount(val accountCode: String, val accountName: String,
var balance : Double = 0.0) {}
vs.
open class BankAccount(val accountCode: String, val accountName: String) {}
var balance : Double = 0.0
The only question you have to ask is "Is this something that should be set via the constructor?" If yes, then use a parameter. If not, use a property. By adding var you're still making the declaration a property, you're just also adding a shortcut to initialize it from the constructor.
If you're coming from a Java background, looking at the Java equivalent would be helpful. It would be something like this:
public class BankAccount {
private final String mAccountCode;
private final String mAccountName;
private double mBalance;
public BankAccount(String accountCode, String accountName, double balance) {
mAccountCode = accountCode;
mAccountName = accountName;
mBalance = balance;
}
public BankAccount(String accountCode, String accountName) {
this(accountCode, accountName, 0.0d)
}
public void setBalance(double balance) {
mBalance = balance;
}
public double getBalance() {
return mBalance;
}
}
vs.
public class BankAccount {
private final String mAccountCode;
private final String mAccountName;
private double mBalance = 0.0d;
public BankAccount(String accountCode, String accountName) {
mAccountCode = accountCode;
mAccountName = accountName;
}
public void setBalance(double balance) {
mBalance = balance;
}
public double getBalance() {
return mBalance;
}
}
Notice that you get a constructor argument for the balance field in the first case. In either case you can update the value with a method call to the setter.
For your second question, when you should and shouldn't use val or var, the answer is "Use var to make the parameter a writable property, use val to make it a read-only property, and use nothing if you just want constructor args.
Again, the Java equivalent of something like this:
open class Example(var writable : Int, val readable : Int, constructorArg : Int) {
// Could use constructor arg to init another property
private val someOtherProperty : Int = constructorArg
// Or in the init block (the Kotlin "constructor" body)
init {
// Or do something with constructArg in the constructor
}
}
Would be something like this:
public class Example {
private int mWritable;
private final int mReadable;
private final int mSomeOtherProperty;
public Example(int writable, int readable, int contructorArg) {
mWritable = writeable;
mReadable = readable;
// Could use constructor arg to init another property
mSometOtherProperty = constructorArg;
// Or do something with constructArg in the constructor
}
public int getWritable() {
return mWritable;
}
public void setWritable(int writable) {
mWritable = writable;
}
public int getReadable() {
return mReadable;
}
The var attribute makes a property that has both a setter and a getter so you can update it.
The val attribute makes a property that only has a getter so you can read it.
The arg with no keyword makes no property - instead it is passed to the constructor for you to use as needed. This is a trivialized example so it does nothing, but in reality you would use it to either initialize other properties or with an init block.
Again, assuming you're coming from a Java background, you can use Intellij to run view the Kotlin byte code, then convert that to Java to see what the differences in the language do.
Here's the first google hit that explains this:
https://medium.com/#mydogtom/tip-how-to-show-java-equivalent-for-kotlin-code-f7c81d76fa8
Hope that helps!
TLDR: Use a parameter if you need to parameterise.
In the first case, you will be able to start an account with a non-zero balance.
If that is a scenario you find useful, it makes sense to make the balance an (optional) parameter. Otherwise, a member variable is more appropriate.

Using complex types in RedisTypedClient (ServiceStack Redis)

I have an example where I want to store an object into Redis.
class CyPoint
{
// Fields...
private bool _Done;
private string _Color;
private string _Position;
private long _Id;
public long Id
{
get { return _Id; }
set
{
_Id = value;
}
}
public string Position
{
get { return _Position; }
set
{
_Position = value;
}
}
public string Color
{
get { return _Color; }
set
{
_Color = value;
}
}
public bool Done
{
get { return _Done; }
set
{
_Done = value;
}
}
}
I am using this code to store the data
var redisCyPoint = redis.As<CyPoint>();
var cpt = new CyPoint
{
Id = redisCyPoint.GetNextSequence(),
Position = "new Vector3(200, 300, 0)",
Color = "new Vector3(.5f, .7f, .3f)",
};
redisCyPoint.Store(cpt);
This works as I am storing strings. But when I change position and color to Vector3 (which is: float, float, float) it only saves 0's. It seems that the Store will not work with complex types. Is this a limitation or is there a way to do this?
Struct's are serialized as a single scalar string value as returned by ToString(). You can implement custom support for Structs by implementing a constructor Vector3(string) that can populate itself from its ToString() value, or implement a static ParseJson(string) method.
Otherwise you can specify custom serializer to handle the serialization, e.g:
JsConfig<Vector3>.SerializeFn = v => "{0},{1},{2}".Fmt(v.X,v.Y,v.Z);
JsConfig<Vector3>.DeSerializeFn = s => {
var parts = s.Split(',');
return new Vector3(parts[0],parts[1],parts[2]);
};

JMockit: expectations on non-mock objects, or, mock objects with more behavior

I am using the class below in a test to take the place of the 'real' Requestor. (The real one does HTTP.) Note that the method in here has void for return type, but it has behavior to mock; it calls back on the callback. I wish that I could write expectations on the method here so that I don't need to write JUnit asserts on counters and such. But I don't see how; I don't see how this can be an #Mock, since I'm not substituting for some other live object, and I don't see how to use a delegate for a function that returns void. Is there a way?
private static class TrivialRequestor implements Requestor {
private final boolean error;
private final int returnedQueueDepth;
TrivialRequestor(boolean error, int returnedQueueDepth) {
this.error = error;
this.returnedQueueDepth = returnedQueueDepth;
}
#Override
public void dispatch(Ticket ticket, FutureCallback<RequestorResult> callback) {
if (error) {
callback.onFailure(new Exception("You asked for it"));
} else {
callback.onSuccess(new RequestorResult(ticket, returnedQueueDepth));
}
}
}

Accesing arraylist property from another class using constructor

So i have a class that makes an array list for me and i need to access it in another class through a constructor but i don't know what to put into the constructor because all my methods in that class are just for manipulating that list. im either getting a null pointer exception or a out of bounds exception. ive tried just leaving the constructor empty but that dosent seem to help. thanks in advance. i would show you code but my professor is very strict on academic dishonesty so i cant sorry if that makes it hard.
You are confusing the main question, with a potential solution.
Main Question:
I have a class ArrayListOwnerClass with an enclosed arraylist property or field.
How should another class ArrayListFriendClass access that property.
Potential Solution:
Should I pass the arraylist from ArrayListOwnerClass to ArrayListFriendClass,
in the ArrayListFriendClass constructor ?
It depends on what the second class does with the arraylist.
Instead of passing the list thru the constructor, you may add functions to read or change, as public, the elements of the hidden internal arraylist.
Note: You did not specify a programming language. I'll use C#, altought Java, C++, or similar O.O.P. could be used, instead.
public class ArrayListOwnerClass
{
protected int F_Length;
protected ArrayList F_List;
public ArrayListOwnerClass(int ALength)
{
this.F_Length = ALength;
this.F_List = new ArrayList(ALength);
// ...
} // ArrayListOwnerClass(...)
public int Length()
{
return this.F_Length;
} // int Length(...)
public object getAt(int AIndex)
{
return this.F_List[AIndex];
} // object getAt(...)
public void setAt(int AIndex, object AValue)
{
this.F_List[AIndex] = AValue;
} // void setAt(...)
public void DoOtherStuff()
{
// ...
} // void DoOtherStuff(...)
// ...
} // class ArrayListOwnerClass
public class ArrayListFriendClass
{
public void UseArrayList(ArrayListOwnerClass AListOwner)
{
bool CanContinue =
(AListOwner != null) && (AListOwner.Length() > 0);
if (CanContinue)
{
int AItem = AListOwner.getAt(5);
DoSomethingWith(Item);
} // if (CanContinue)
} // void UseArrayList(...)
public void AlsoDoesOtherStuff()
{
// ...
} // void AlsoDoesOtherStuff(...)
// ...
} // class ArrayListFriendClass
Note, that I could use an indexed property.