Java - Remove "Optional" from a variable (convert) - java

for a piece of homework, I have to set a variable. The set method given to me, converts that into "Optional". However, I have to store this variable in an ArrayList which doesn't allow Optional variables.How can I convert the variable so it is no longer Optional?
The set method:
public void setParentVertex(IVertex<T> parentVertex)
{
if(parentVertex == null)
this.parentVertex = Optional.empty();
else
this.parentVertex = Optional.of(parentVertex);
}
Where I'm trying to use it:
ArrayList<IVertex<T>> path = new ArrayList<IVertex<T>>();
IVertex<T> parent = current.getLabel().getParentVertex();
path.add(parent);
The error I keep receiving is: "Error: incompatible types: Optional> cannot be converted to IVertex" due to the line where I declare the variable "parent".
Thank you.

Here is the correct version
List<IVertex<T>> path = new ArrayList<IVertex<T>>();
current.getLabel().getParentVertex().ifPresent(path::add)
Also it would be good to rewrite setParentVertex function:
public void setParentVertex(IVertex<T> parentVertex) {
this.parentVertex = Optional.ofNullable(parentVertex);
}

I think you don't have to add it to your list, if there is no value. So just do
if(nameOfOptional.isPresent()){
list.add(nameOfOptional.get());
}

First, add a check to find the value is present or not (by calling isPresent()) and then if the value is present then add to your ArrayList path object as shown below:
ArrayList<IVertex<T>> path = new ArrayList<>();
Optional<IVertex<T>> parent = current.getLabel().getParentVertex();
if(parent.isPresent()) {
path.add(parent.get());
}
or the shorter form is shown below which uses ifPresent method:
ArrayList<IVertex<T>> path = new ArrayList<>();
Optional<IVertex<T>> parent = current.getLabel().getParentVertex();
parent.ifPresent(path::add);
Also, I suggest you have a look at the Optional API methods here.
As a side note, I recommend you to use diamond <> operator while declaring generic types (like shown above i.e., new ArrayList<>()) , so that your code will be less verbose.

Related

Java List auto create and add

Is it possible to replace this:
if (archiveUnitEntity.getArchiveCaseEntityList() == null) {
archiveUnitEntity.setArchiveCaseEntityList(new ArrayList<ArchiveCaseEntity>());
}
archiveUnitEntity.getArchiveCaseEntityList().add(archiveCaseEntity);
This something like that:
ifListNullCreate(archiveUnitEntity.getArchiveCaseEntityList()).Add(archiveCaseEntity);
If you can change the method getArchiveCaseEntityList() then you could add that null check into the getter and update it there (or create another method if you need it to be null in some cases). If not, then you could create the method you want wherever you want/need.
But I don't think there is a built-in method to do that.
Here's one possible solution.
In the ArchiveUnitEntity class, declare the list like this, so that it's not null on creation.
private List<ArchiveCaseEntity> archiveCaseEntityList = new ArrayList<>();
You might also want to change the setter for that field, so that it can't get set to null.
public void setArchiveCaseEntityList(ArchiveCaseEntityList archiveCaseEntityList) {
this.archiveCaseEntityList = archiveCaseEntityList == null ? new ArrayList<ArchiveCaseEntity>() : archiveCaseEntityList;
}
It's better to initialize your archiveCaseEntityList attribute during the creation of the instance of archiveUnitEntity. Avoiding null object can simplify a lot of things :)
Directly when you declare your attribute :
private List<ArchiveCaseEntity> archiveCaseEntityList = new ArrayList<>();
or in constructor :
public ArchiveUnitEntity(){
this.archiveCaseEntityList = new ArrayList<>();
}
And finally, you could build a new method to manage ArchiveCaseEntity addition :
public void addArchiveCaseEntity(ArchiveCaseEntity entity){
this.archiveCaseEntityList.add(entity);
}

Access Lambda Arguments with Groovy and Spock Argument Capture

I am trying to unit test a Java class with a method containing a lambda function. I am using Groovy and Spock for the test. For proprietary reasons I can't show the original code.
The Java method looks like this:
class ExampleClass {
AsyncHandler asynHandler;
Component componet;
Component getComponent() {
return component;
}
void exampleMethod(String input) {
byte[] data = input.getBytes();
getComponent().doCall(builder ->
builder
.setName(name)
.data(data)
.build()).whenCompleteAsync(asyncHandler);
}
}
Where component#doCall has the following signature:
CompletableFuture<Response> doCall(Consumer<Request> request) {
// do some stuff
}
The groovy test looks like this:
class Spec extends Specification {
def mockComponent = Mock(Component)
#Subject
def sut = new TestableExampleClass(mockComponent)
def 'a test'() {
when:
sut.exampleMethod('teststring')
then:
1 * componentMock.doCall(_ as Consumer<Request>) >> { args ->
assert args[0].args$2.asUtf8String() == 'teststring'
return new CompletableFuture()
}
}
class TestableExampleClass extends ExampleClass {
def component
TestableExampleClass(Component component) {
this.component = component;
}
#Override
getComponent() {
return component
}
}
}
The captured argument, args, shows up as follows in the debug window if I place a breakpoint on the assert line:
args = {Arrays$ArrayList#1234} size = 1
> 0 = {Component$lambda}
> args$1 = {TestableExampleClass}
> args$2 = {bytes[]}
There are two points confusing me:
When I try to cast the captured argument args[0] as either ExampleClass or TestableExampleClass it throws a GroovyCastException. I believe this is because it is expecting Component$Lambda, but I am not sure how to cast this.
Accessing the data property using args[0].args$2, doesn't seem like a clean way to do it. This is likely linked to the casting issue mentioned above. But is there a better way to do this, such as with args[0].data?
Even if direct answers can't be given, a pointer to some documentation or article would be helpful. My search results discussed Groovy closures and Java lambdas comparisons separately, but not about using lambdas in closures.
Why you should not do what you are trying
This invasive kind of testing is a nightmare! Sorry for my strong wording, but I want to make it clear that you should not over-specify tests like this, asserting on private final fields of lambda expressions. Why would it even be important what goes into the lambda? Simply verify the result. In order to do a verification like this, you
need to know internals of how lambdas are implemented in Java,
those implementation details have to stay unchanged across Java versions and
the implementations even have to be the same across JVM types like Oracle Hotspot, OpenJ9 etc.
Otherwise, your tests break quickly. And why would you care how a method internally computes its result? A method should be tested like a black box, only in rare cases should you use interaction testing,where it is absolutely crucial in order to make sure that certain interactions between objects occur in a certain way (e.g. in order to verify a publish-subscribe design pattern).
How you can do it anyway (dont!!!)
Having said all that, just assuming for a minute that it does actually make sense to test like that (which it really does not!), a hint: Instead of accessing the field args$2, you can also access the declared field with index 1. Accessing by name is also possible, of course. anyway, you have to reflect on the lambda's class, get the declared field(s) you are interested in, make them accessible (remember, they are private final) and then assert on their respective contents. You could also filter by field type in order to be less sensitive to their order (not shown here).
Besides, I do not understand why you create a TestableExampleClass instead of using the original.
In this example, I am using explicit types instead of just def in order to make it easier to understand what the code does:
then:
1 * mockComponent.doCall(_ as Consumer<Request>) >> { args ->
Consumer<Request> requestConsumer = args[0]
Field nameField = requestConsumer.class.declaredFields[1]
// Field nameField = requestConsumer.class.getDeclaredField('arg$2')
nameField.accessible = true
byte[] nameBytes = nameField.get(requestConsumer)
assert new String(nameBytes, Charset.forName("UTF-8")) == 'teststring'
return new CompletableFuture()
}
Or, in order to avoid the explicit assert in favour of a Spock-style condition:
def 'a test'() {
given:
String name
when:
sut.exampleMethod('teststring')
then:
1 * mockComponent.doCall(_ as Consumer<Request>) >> { args ->
Consumer<Request> requestConsumer = args[0]
Field nameField = requestConsumer.class.declaredFields[1]
// Field nameField = requestConsumer.class.getDeclaredField('arg$2')
nameField.accessible = true
byte[] nameBytes = nameField.get(requestConsumer)
name = new String(nameBytes, Charset.forName("UTF-8"))
return new CompletableFuture()
}
name == 'teststring'
}

List of regex results instead of first result in Kotlin

Using the following code, I can set a couple variables to my matches. I want to do the same thing, but populate a map of all instances of these results. I'm struggling and could use help.
val (dice, level) = Regex("""([0-9]*d[0-9]*) at ([0-9]*)""").matchEntire(text)?.destructured!!
This code works for one instance, none of my attempts at matching multiple are working.
Your solution is short and readable. Here are a few options the one you use is largely a matter of preference. You can get a Map directly by using the associate method as follows.
val diceLevels = levelMatches.associate { matched ->
val (diceTwo,levelTwo) = matched.destructured
(levelTwo to diceTwo)
}
Note: This creates an immutable map. If you want a MutableMap, you can use associateTo.
If you want to be concise, you can simplify out the destructuring to local variables and index the groups directly.
val diceLevels = levelMatches.associate {
(it.groupValues[2] to it.groupValues[1])
}
Or, using let, you can also avoid needing to declare levelMatches as a local variable if it isn't used elsewhere --
val diceLevels = Regex("([0-9]+d[0-9]+) at ([0-9]+)")
.findAll(text)
.let { levelMatches ->
levelMatches.associate {
(it.groupValues[2] to it.groupValues[1])
}
}
I realized this was no where near as complicated as I was making it. Here was my solution. Is there something more elegant?
val levelMatches = Regex("([0-9]+d[0-9]+) at ([0-9]+)").findAll(text)
levelMatches.forEach { matched ->
val (diceTwo,levelTwo) = matched.destructured
diceLevels[levelTwo] = diceTwo
}

How can I create an array of objects in Kotlin without initialization and a specific number of elements?

I want to create an Array of objects with a specific number of elements in Kotlin, the problem is I don't now the current values for initialization of every object in the declaration, I tried:
var miArreglo = Array<Medico>(20, {null})
in Java, I have this and is exactly what I want, but i need it in Kotlin. :
Medico[] medicos = new Medico[20];
for(int i = 0 ; i < medicos.length; i++){
medicos[i] = new Medico();
}
What would be the Kotlink equivalent of the above Java code?
Also, I tried with:
var misDoctores = arrayOfNulls<medic>(20)
for(i in misDoctores ){
i = medic()
}
But I Android Studio show me the message: "Val cannot be reassigned"
The Kotlin equivalent of that could would be this:
val miArreglo = Array(20) { Medico() }
But I would strongly advice you to using Lists in Kotlin because they are way more flexible. In your case the List would not need to be mutable and thus I would advice something like this:
val miArreglo = List(20) { Medico() }
The two snippets above can be easily explained. The first parameter is obviously the Array or List size as in Java and the second is a lambda function, which is the init { ... } function. The init { ... } function can consist of some kind of operation and the last value will always be the return type and the returned value, i.e. in this case a Medico object.
I also chose to use a val instead of a var because List's and Array's should not be reassigned. If you want to edit your List, please use a MutableList instead.
val miArreglo = MutableList(20) { Medico() }
You can edit this list then, e.g.:
miArreglo.add(Medico())
If you want list of nullable objects, we can do something like this
val fragment : Array<Fragment?> = Array(4) { null }


Passing parameter to class property in Java

I have this property in a visual basic class. NET 2008, the property in addition to the get and set has a parameter called "pParam. "
Public Property UpdateField(ByVal pParam As String) As String
Get
Return Me.idField
End Get
Set(ByVal value As String)
Me.idField = value
If pParam = "NEW" Then
// some code here
End If
End Set
End Property
which is the equivalent of this in java code?
to use I do the following:
oClass.UpdateField("NEW") = 1850
I have this code in java
public void setUpdateField(String idField) {
this.idField = idField;
}
public String getUpdateField() {
return idField;
}
but I need to put the parameter "pParam"
Thanks in advance.
What you've got in the .NET code is an indexer in C# terms. There's no equivalent in Java - you'll just need to take two parameters:
public void setUpdateField(String idField, String pParam) {
...
}
Frankly I think it's a little odd that the "getter" in .NET doesn't seem to use the index...

Categories