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.
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.
Vavr's Either seems to solve one of my problems were some method does a lot of checks and returns either CalculationError or CalculationResult.
Either<CalculationError, CalculationResult> calculate (CalculationData calculationData) {
// either returns Either.left(new CalculationError()) or Either.right(new CalculationResult())
}
I have a wrapper which stores both errors and results
class Calculation {
List<CalculationResult> calculationResults;
List<CalculationError> calculationErrors;
}
Is there any neat solution to transform stream from Collection<CalculationData> data to Calculation?
This can be easily done using a custom collector. With a bit of pseudo code representing the Either:
Collector<Either<CalculationError, CalculationResult>, ?, Calculation> collector = Collector.of(
Calculation::new,
(calc, either) -> {
if (either has error) {
calc.calculationErrors.add(either.error);
} else {
calc.calculationResults.add(either.result);
}
},
(calc1, calc2) -> {
calc1.calculationErrors.addAll(calc2.calculationErrors);
calc1.calculationResults.addAll(calc2.calculationResults);
return calc1;
}
);
Calculation calc = data.stream()
.map(this::calculate)
.collect(collector);
Note that Calculation should initialize its two lists (in the declaration or a new constructor).
Well, you're using vavr, so 'neat' is right out. Tends to happen when you use tools that are hostile to the idiomatic form of the language. But, then again, 'neat' is a nebulous term with no clear defined meaning, so, I guess, whatever you think is 'neat', is therefore 'neat'. Neat, huh?
Either itself has the sequence method - but both of them work the way Either is supposed to work: They are left-biased in the sense that any Lefts present is treated as erroneous conditions, and that means all the Right values are discarded if even one of your Eithers is a Left. Thus, you cannot use either of the sequence methods to let Either itself bake you a list of the Right values. Even sequenceRight won't do this for you (it stops on the first Left in the list and returns that instead). The filter stuff similarly doesn't work like that - Either very much isn't really an Either in the sense of what that word means if you open a dictionary: It does not mean: A homogenous mix of 2 types. It's solely a non-java-like take on exception management: Right contains the 'answer', left contains the 'error' (you're using it correctly), but as a consequence there's nothing in the Either API to help with this task - which in effect involves 'please filter out the errors and then do something' ("Silently ignore errors" is rarely the right move. It is what is needed here, but it makes sense that the Either API isn't going to hand you a footgun. Even if you need it here).
Thus, we just write it plain jane java:
var calculation = new Calculation();
for (var e : mix) {
if (e.isLeft()) calculation.calculationErrors.add(e.getLeft());
if (e.isRight()) calculation.calculationResult.add(e.getRight());
}
(This presumes your Calculation constructor at least initializes those lists to empty mutables).
NB: Rob Spoor's answer also assumes this and is much, much longer. Sometimes the functional way is the silly, slow, unwieldy, hard to read, way.
NB2: Either.sequence(mix).orElseRun(s -> calculation.errors = s.asJava()); is a rather 'neat' way (perhaps - it's in the eye of the beholder) of setting up the errors field of your Calculation class. No joy for such a 'neat' trick to fill the 'results' part of it all, however. That's what the bulk of my answer is trying to explain: There is no nice API for that in Either, and it's probably by design, as that involves intentionally ignoring the errors in the list of Eithers.
Since you are using VAVr, you may consider using Traversable instead of Collection. This will give you the method partition, which can be used to classify your list of Eithers into two groups like so:
Traversable<Either<CalculationError, CalculationResult>> calculations = ...;
var partitionedCalcs = calculations.partition(Either::isRight);
var results = partitionedCalcs._1.map(Either::getRight);
var errors = partitionedCalcs._2.map(Either::getLeft);
Calculation calcs = new Calculation(results, errors);
If you don't want to change your existing use of Collection to use a Traversable, then you can easily convert between them by using, for example, List.ofAll(Iterator) and Value.toJavaCollection(Function).
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.
I'm using the for-each construct in Java as follows:
public int getNumRStations() {
int numRoutes = 0;
for (ArrayList<Route> route : routes) {
numRoutes += route.size();
}
return numRoutes;
}
NetBeans shows a warning/notice that says "Can use functional operations". Upon automatically resolving it, the newly generated code shows this:
public int getNumRStations() {
int numRoutes = 0;
numRoutes = routes.stream().map((route) -> route.size()).reduce(numRoutes, Integer::sum);
return numRoutes;
}
Why is NetBeans warning me of this? I know I'm not supposed to blindly trust IDEs, so that's why I'm asking.
What is that new line supposed to do? I haven't seen anything like it, in real life or in class.
That looks like NetBeans suggesting refactoring your sum operation as a Java 8 "lambda" or functional programming operation using the map and reduce functions from the Stream interface. You must be using a Java 8 JDK with NetBeans.
Breaking down what it's doing:
the "map()" function is performing a count of all of your route sizes in your routes array list,
the "reduce()" function is then performing a sum of those individual sizes to get the final result for the total number of routes.
The map() and reduce() functions are documented in the Java 8 documentation for the Stream interface available at this link
This answer addresses "what it is" but doesn't address "why it's better". I will admit to still learning about these constructs myself.
So #paisanco already explained about what each function does.
I agree that the modification the IDE suggested is more complex than the original.
If I were asked to select between the original one and the IDE's recommendation, then I will choose the original one.
However, here is a simpler (and more preferred) way for your example.
public int getNumRStations() {
return routes.stream().mapToInt(x -> x.size()).sum();
}
Explanation is simpler in this case, too.
For each routes' element x, change it into x.size() and sum them up.
x -> x.size() is called a lambda expression, or anonymous function.
It's like
int function(x) {
return x.size();
}
(I omitted the parameter type. The type is implicitly selected by the Java compiler.)
This function is applied to each of the collection's element. This is what mapToInt(lambda exp) method does.
sum() method doesn't seem to need explanation.
Simple, isn't it?
Recently I refactored the code of a 3rd party hash function from C++ to C. The process was relatively painless, with only a few changes of note. Now I want to write the same function in Java and I came upon a slight issue.
In the C/C++ code there is a C preprocessor macro that takes a few integer variables names as arguments and performs a bunch of bitwise operations with their contents and a few constants. That macro is used in several different places, therefore its presence avoids a fair bit of code duplication.
In Java, however, there is no equivalent for the C preprocessor. There is also no way to affect any basic type passed as an argument to a method - even autoboxing produces immutable objects. Coupled with the fact that Java methods return a single value, I can't seem to find a simple way to rewrite the macro.
Avenues that I considered:
Expand the macro by hand everywhere: It would work, but the code duplication could make things interesting in the long run.
Write a method that returns an array: This would also work, but it would repeatedly result into code like this:
long tmp[] = bitops(k, l, m, x, y, z);
k = tmp[0];
l = tmp[1];
m = tmp[2];
x = tmp[3];
y = tmp[4];
z = tmp[5];
Write a method that takes an array as an argument: This would mean that all variable names would be reduced to array element references - it would be rather hard to keep track of which index corresponds to which variable.
Create a separate class e.g. State with public fields of the appropriate type and use that as an argument to a method: This is my current solution. It allows the method to alter the variables, while still keeping their names. It has the disadvantage, however, that the State class will get more and more complex, as more macros and variables are added, in order to avoid copying values back and forth among different State objects.
How would you rewrite such a C macro in Java? Is there a more appropriate way to deal with this, using the facilities provided by the standard Java 6 Development Kit (i.e. without 3rd party libraries or a separate preprocessor)?
Option 3, create you own MutableInteger wrapper class.
struct MutableInteger{
public MutableInteger(int v) { this.value = value;}
public int value;
}
public void swap3( MutableInteger k, MutableInteger l, MutableInteger m) {
int t = m.value;
m.value = l.value
l.value=k.value;
k.value=t;
}
Create a separate class e.g. State
with public fields of the appropriate
type and use that as an argument to a
method
This, but as an intermediate step. Then continue refactoring - ideally class State should have private fields. Replace the macros with methods to update this state. Then replace all the rest of your code with methods that update the state, until eventually your program looks like:
System.out.println(State(System.in).hexDigest());
Finally, rename State to SHA1 or whatever ;-)