I have a piece of code in java that i want to convert to swift but can't find a swift equivalent to java's Enumeration interface, any help will be highly appreciated.
Java Enumeration
In Java, Enumeration is a class that enables access to a sequence of elements one at a time. Calling hasMoreElements() returns a bool indicating whether there is another element, and nextElement() moves on to the next item in the sequence and returns it.
My Java Code
import java.util.Enumeration;
private Hashtable<String, Marker> mMarkers;
final Enumeration<String> refs = mMarkers.keys();
while (refs.hasMoreElements()) {
final String ref = refs.nextElement();
}
Question
Does Swift contain an equivalent object?
Yes, Swift contains an equivalent, but in true Swift fashion, the core functionality takes the form of a Protocol defined in the Swift Standard Library, which is then implemented by other protocols and objects in the standard library.
This Swift documentation gives you everything you need to know.
Basically, IteratorProtocol defines an interface very similar to Java's Enumeration. You can then get a special iterator object out of a collection and use it in much the same way.
Sample
(No import necessary)
private var mMarkers: Dictionary<String, Marker>
let refsIterator = mMarkers.keys.makeIterator()
while let ref = refsIterator.next() {
// do something with ref
}
Most of the time, however, unless you need high customization you can just use a for-in loop:
private var mMarkers: Dictionary<String, Marker>
for ref in mMarkers.keys {
// do something with ref
}
Difference Between Java and Swift Implementation
Whether we use Java or Swift, it is important to ensure that a next value exists before we try to do something with that value.
In the case of Java's Enumerator, the developer is expected to call hasMoreElements() before each call to next(), in order to ensure that next() will not be trying to access a value that does not exist. So basically, hasMoreElements() performs the safety check and next() simply attempts to give you the next value. If a "next value" does not exist, Java throws an exception from next().
Swift handles things a bit differently. The safety check is instead done in next(), the same function that also returns a value if it exists. So if the safety check fails, nil is returned; otherwise, the next value is fetched and returned. Because next() returns Element? ('Optional') rather than Element, we can use while let on the returned value. while let creates a condition that is only true if next() is not nil. In addition, when this condition is satisfied, the returned value is automatically added to a constant with a non-Optional type that may be used in the scope of the loop.
This means that in Swift, you could theoretically keep calling next() as many times as you want after the sequence has been exhausted, but you will just keep getting nil back. Swift largely prefers returning optionals in places like this rather than throwing errors, which are usually reserved for things going wrong. In fact, it wasn't until Swift 2.0 that errors could even be thrown and caught in Swift.
Related
I have the following code
//assume we have a list of custom type "details" already constructed
for(int i = 0; i < details.size(); ++i) {
CallerID number = details.get(i).getNextNumber();
ClientData.addToClient(number);
}
I have oversimplified the code. The enum CallerID and the ClientData object work as intended. I am asking for help converting this loop to a lambda function so I can understand the logic of how to do so, then fill in the appropriate code as needed.
Let's first write it as a modern basic for loop and golf it a bit, just so we're comparing apples to apples:
for (var detail : details) clientData.addToClient(detail.getNextNumber());
And this is probably the right answer. It is local var, exception, and control flow transparent (which is what you want), and short.
The lambda form is this, but it's got downsides (mostly, those transparencies). It also isn't any shorter. You shouldn't write it this way.
details.stream().forEach(d -> clientData.addToClient(detail.getNextNumber());
You may be able to just remove stream() from that. But probably not.
Generally when people say "I want it in lambda form", that's not because someone is holding a gun to your head - you are saying that because somebody peddling a religion of sorts to you told you that 'it was better' and that this 'will scale'. Realize that they are full of it. There can be advantages to 'functional style', but none of these snippets are functional. A true functional style would involve a bunch of side-effect-free transformations, and then returning something.
.addToClient? You've lost the functional game there - you would want to instead convert each detail to something (presumably a ClientID), and from there construct an immutable object from that stream. You'd 'collect' your ClientIDs into a clientData object.
Let's say for example that clientData is just a 'list of ClientIDs' and nothing more. Then you'd write something like this:
var clientData = details.stream()
.map(MyDetailClass::getNextNumber)
.collect(Collectors.toList());
Is this better? No. However, if you're looking for 'a stream-style, lambda-based functional take on things', that qualifies. The output is constructed by way of collection (and not forEach that does a side-effect operation), and all elements involved are (or can be) immutable.
There's no particular reason why you'd want this, but if for some reason you're convinced this is better, now you know what you want to do. "Just replace it with a lambda" doesn't make it 'functional'.
I am asking for help converting this loop to a lambda function so I can understand the logic of how to do so, then fill in the appropriate code as needed.
A Function returns a value. As you are just updating something what you need is a Consumer which accepts a single argument of a list of some detail. Assuming those are in a Class named SomeDetails, here is how you would do it.
As you iterating over some structure limited by size and using get(i) I am presuming a list is required here.
List<SomeDetails> details = new ArrayList<>(); // then populated
// lambda definition
Consumer<List<SomeDetails>> update = (lst)-> {
for(SomeDetails detail : lst) {
CallerID number = detail.getNextNumber();
ClientData.addToClient(number);
}
};
And then invoke it like this, passing the List.
update.accept(details);
All the above does is encapsulate the for loop (using the enhanced version for simplicity) and perform the operation.
If this is all you wanted, I would recommend just doing it as you were doing it sans the lambda.
Assume I have a Java method
public X findX(...)
which tries to find an Object of type X fulfilling some conditions (given in the parameters). Often such functions cannot guarantee to find such an object. I can think of different ways to deal with this:
One could write an public boolean existsX(...) method with the same signature which should be called first. This avoids any kind of exceptions and null handling, but probably you get some duplicate logic.
One could just return null (and explain this in javadoc). The caller has to handle it.
One could throw a checked exception (which one would fit for this?).
What would you suggest?
The new Java 8 Optional class was made for this purpose.
If the object exists then you return Optional.of(x) where x is the object, if it doesn't then return Optional.empty(). You can check if an Optional has an object present by using the isPresent() method and you can get the object using get().
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
If you can't use Optional I would go with option 2.
In the case of 1. You'd be doing double work, first you have to check if X exists, but if it does, you're basically discarding the result, and you have to do the work again in findX. Although the result of existsX could be cached and checked first when calling findX, this would still be an extra step over just returning X.
In the case of 3. To me this comes down to usability. Sometimes you just know that findX will return a result (and if it doesn't, there is a mistake somewhere else), but with a checked exception, you would still have to write the try and (most likely empty) catch block.
So option 2 is the winner to me. It doesn't do extra work, and checking the result is optional. As long as you document the null return, there should be no problems.
Guava (potentially other libraries, too) also offers an Optional class that might be worth exploring if your project uses Guava since you seem to not use Java 8.
If you
don't/can't/won't use Java 8 and its accompanying Optional type
don't want another library dependency (like Guava) for a single class implementation
but
you want something more robust than methods that can return null for which you have to have a check in all consumers (which was the standard before Java 8)
then writing your own Optional as an util class is the easiest option.
This is probably more a question about functional programming than about Java 8 specifically, but it's what I'm using right now.
I have a source object (could represent a repository, or a session..., doesn't matter here) that has a method retrieveSomething() that returns an Optional<SomethingA>.
I have a method somewhere that returns a Something, by calling retrieveSomething() and providing a default value in case the optional was empty, as follows:
return source.retrieveSomething()
.orElseGet(() -> provideDefaultValue());
Now I want to modify this code so that in case the source didn't contain any value yet (so the optional was empty), the source is updated with the provided default value.
Of course, I could easily do that inside a lambda expression code block:
return source.retrieveSomething()
.orElseGet(() -> {
Something sth = provideDefaultValue()
source.putSomething(sth);
return sth;
});
But if I understand correctly, I'm not supposed to use functions that cause side effects. So what's the "correct" (functional) way to do this, keeping the benefit of using Optional (in real code I'm actually also performing a map operation on it, but that's irrelevant here) ?
You could follow the way Java does this with Map.computeIfAbsent()
which takes a second parameter which is a function on how to compute and insert the record:
So your code would become:
Something something = source.computeIfAbsent(sth, (k)->provideDefaultValue());
An advantage of using a lambda to compute the default instead of just passing it in, is the lambda will only be evaluated if it needs to be so if computing the default is expensive, you only have to pay it when you need it.
From a conceptual standpoint, you use the optional pattern to deal with the absence of a return value. This means, if your source instance doesn't contain a value for you to use, you have the choice of providing a default value to use in its place.
It is not advised to modify the Optional directly to provide its value; that instance may be temporal and will differ on subsequent calls to retrieve it.
Since a function call truly governs what's returned by that Optional, the only approach you have if you truly want to go down this route is to modify how that value is computed. This really should be done from within the function providing the Optional, but it could be done outside of it if necessary.
Since there's not enough code structure here to truly write up some example, I will describe the steps:
Outside of the method providing the Optional, you write the same closure as you did before, with the side effect of adjusting the value used to compute the original Optional. This is likely a field of some sort.
Inside of the method providing the Optional, you ensure that you don't expose provideDefaultValue anywhere else (since they won't need it), and use a boolean conditional before you package the Optional.
return value == null ? Optional.of(provideDefaultValue()) : Optional.of(value);
...but that really defeats the purpose of the Optional, as you're still doing a null check.
A slightly better approach to the above would be to compute value in such a way that it was either itself or the default value, and return the Optional of that...
value = computeValue();
if(null == value) {
value = provideDefaultValue();
}
return Optional.of(value);
...but again, seriously defeating the purpose of Optional, as you're doing null checks.
An answer I came up with myself, which I'm not entirely satisfied with, but may serve as an example of what I'm looking for:
I could implement something similar to a Pair<V1,V2> class and then map the Optional<Something> to a Pair<Something, Boolean> where the Boolean value would indicate whether or not the value was a generated default:
Pair<Something, Boolean> somethingMaybeDefault =
source.retrieveSomething()
.map(sth -> new Pair<Something, Boolean>(sth, false))
.orElseGet(() -> new Pair<Something, Boolean>(provideDefaultValue(), true));
Then I'd update in case the boolean is false:
if (somethingMaybeDefault.value2()) {
source.putSomething(somethingMaybeDefault.value1());
}
And finally return the new value:
return somethingMaybeDefault.value1();
Of course, this uses imperative style for the update, but at least the functions remain pure.
I'm not sure this is the best possible answer though.
I am trying to implement this but I can't find a good paper or description of how to do it, could you guys point me in the right direction please? I do have an implementation of it in C# but I don't know enough to just convert the code to Java.
As per a comment I'm adding some of the C# Code I haven't been able to convert to Java:
//T with the smallest func(t)
static T MinBy<T, TComparable>(this IEnumerable<T> xs, Func<T, TComparable> func) where TComparable : IComparable<TComparable>{
return xs.DefaultIfEmpty().Aggregate((maxSoFar, elem) => func(elem).CompareTo(func(maxSoFar)) > 0 ? maxSoFar : elem);
}
//returns an ordered set of nearest neighbors
static IEnumerable<Stop> NearestNeighbors(this IEnumerable<Stop> stops){
var stopsLeft = stops.ToList();
for (var stop = stopsLeft.First(); stop != null; stop = stopsLeft.MinBy(s => Stop.Distance(stop, s))){
stopsLeft.Remove(stop);
yield return stop;
}
}
I assume you are not familiar with C#. So I will try to explain some of the things in short.
IEnumerable<T> is C#'s equivalent of java's Iterable<T>
Func<T, V> is an abstraction of a method who's input is T and return value is V. C#, unlike Java, supports closures, but they are effectively like java anonymous classes, without all the syntactic fuss around. So basically, the second argument of MinBy is a means to extract the property from T is relevant for comparison. You could easily implement the very same abstraction with an anonymous class, but it will not be as concise.
The strange this modifier that comes before the first argument is saying that this is an extension method. It solely serves a syntactic sugar purpose. When a method is define like this, it means that it can be called on the instance of the first argument (that has the this modifier before it). This allowes you to write code like:
IEnumerable<String> seq = getS();
seq.MinBy(/*bla*/);
instead of explicitly specifying the Utility class the static method is defined in:
MyUtility.MinBy(s, /*bla*/);
You probably do not need this high level of abstraction (and lets face it, java is simply not built for it today) so what you want to do is to define a method instead of MinBy that inputs an Iterable leftStops and another Stop currentStop and finds the closest stop to currentStop from leftStops.
Something like:
Stop findClosest(Stop currentStop, Iterable<Stop> left stops) {/*implement me*/}
That done, lets turn to NearestNeighbors itself. What is that yield return? it is a very powerful way to implelent iterators in .Net. I feel that a full explanation on its workings is beyond the scope of our discussion, so I have rewritten the method not to use this feature in a way that conserves its functionality (and removed the this qualifier of its first argument):
static IEnumerable<Stop> NearestNeighbors(IEnumerable<Stop> stops){
IEnumerable<Stop> result = new List<stop>();
var stopsLeft = stops.ToList();
for (var stop = stopsLeft.First(); stop != null; stop = stopsLeft.MinBy(s => Stop.Distance(stop, s))){
stopsLeft.Remove(stop);
result.Add(stop);
}
return result;
}
So we are left with the following algorithm:
Input a list of Stops
next-stop = first-stop
Remove next-stop from the Stop list
Find the closest stop to next-stop and set next-stop=closest
if there are more stops, go to 3
Return the stops in the order they were visited.
Hopefully it is clearer now.
I know this is a dumb question, but its really bugging me.
Take the following:
public <TParseable> LinkedList<TParseable> readAllParseable(
Parseable<TParseable> parseable, boolean close) throws IOException
{
LinkedList<TParseable> list = new LinkedList<TParseable>();
byte[] delim = parseable.getDelimiterValue();
boolean skipNL = parseable.skipNewLines();
while(ready())
{
byte[] data = readTo(delim);
parseable.parse(data);
System.out.println(parseable);
list.add((TParseable)parseable);
}
return list;
}
The println statement outputs the expected toString() value of parseable each time after the call to parseable.parse(data). However, the returned list has the correct number of elements, but they are all equal to the last value of parseable before the loop completed.
Is this because the list.add(xxx) parameter is passed by pointer rather than value?
You only ever have a single instance of parseable in the code you posted. When you call add(parseable) you are adding a reference ("pointer" isn't really correct in Java) to parseable in your list.
By calling it repeatedly, without changing what object parseable refers to, you are simply adding more references to the same object to your list.
New objects are only ever created by the new keyword.
You're putting in the same parseable object into the list each time. Each time parseable parses some data, it is being processed using the same parseable object.
the object parseable is the same through the entire method. I assume that when you call parseable.parse(data) it changes the internal data in parseable. Since you keep putting the same object in the list, you are just operating on the same object every iteration.
I think you conceptual problem is one of terminology. If I change "value" to "state", perhaps it will help clarify things ...
The println statement outputs the
expected toString() state of parseable
each time after the call to
parseable.parse(data).
However, the returned list has the
correct number of elements, but they
are all equal to the last state of
parseable before the loop completed.
In reality, your program is using only one Parseable instance, and the method calls on that instance are changing its state.
Is this because the list.add(xxx)
parameter is passed by pointer rather
than value?
No. It is because the instance's state (as shown by toString()) is changing.
In fact, Java uses pass-by-value semantic for all parameters in method and constructor calls, irrespective of the type. The slightly confusing thing is that the "value" that is passed when you pass an Object / array in Java is a reference.
The three basic parameter passing mechanisms supported by programming languages are:
pass-by-value where you copy the value which might be a primitive value, a pointer / reference value, or (in some languages) a structured value. (In some languages, a value can be copied back on return, but that's just a logical extension of pass-by-value.)
pass-by-reference where you pass the address of a variable in the caller, allowing the callee to change that variable, and/or see the results of something else changing the variable.
pass-by-name which was a "clever" mechanism used in Algol-60 that turned out to be expensive to implement and too difficult for most programmers to use effectively.
I would stay away from using the terminology "pass by pointer". It is really just another way of saying "pass-by-value of a pointer" ... and if you try to think of it as something different, you only end up confused.