A very simple example:
val map = mapOf("one" to 1, "two" to 2)
map.forEach{k, v -> if (k == "one") println(v)} //Java API
map.forEach{(k, v) -> if (k == "two") println(v)} //Kotlin extension
I am confused by the IDE warning Java Map.forEach method call should be replaced with Kotlin's forEach for the second line. I don't understand why should I replace it. They seem to work identically, and the only difference is the java method requiring 2 less symbols to type. Any ideas?
If nothing else, it's an inline function, and can more efficiently do things like mutate state elsewhere or smoothly incorporate suspend functions.
Using the same forEach everywhere is simpler than having to track which one you're using at any given point.
In addition to other answers: the Java method is only available in Kotlin/JVM, while the Kotlin function is cross-platform and can also be used in Kotlin/Native and Kotlin/JS. So without good reasons to use the Java version, it makes sense to default to the Kotlin version with its greater compatibility.
Related
While implementing a self-referencing lazy-list version to calculate fibonacci numbers in Java, I came across this:
LazyList<Long> fibs = new LazyList<>(0L,
() -> new LazyList<>(1L,
() -> fibs.zip(fibs.getTail()).map(p -> p.getA() + p.getB())
)
);
See https://gist.github.com/lenalebt/e627e13d034011ac156d44917fe466d3 for the complete code. The lazy list is calculating values on demand and caches them for later re-use.
It complains in the second lambda about "fibs might not have been initialized". While I think I understand why it complains and have a workaround (in the gist, using a setter for the tail), I am looking for a solution that
works with an immutable interface to the outside world (so no setters on LazyList!)
does not completely change the idea of that lazy list (which effectively is a Stream from Scala)
I know e.g. https://dzone.com/articles/do-it-java-8-recursive-and (last approach). While this works nicely, I wanted to formulate an example for lazy evaluation with memoization and self-reference, which the Java-Stream solution presented there is not.
I was trying to port this example from Scala to Java: http://derekwyatt.org/2011/07/29/understanding-scala-streams-through-fibonacci/
I'm a colleague of the thread creator - we already talked about the problem.
The JVM cannot pass an uninitialized reference into the lambda. The reference is not initialized because the constructor call can fail - same as with a method call. Scala allows this scenario, because there are ynthetic classed generated that implement the "property" fibs instead of a variable. Nice finding: Some old Scala compilers don't allow this scenario either and state something like "illegal forward reference" (old bugs). With Java, one would work around with a property-like intermediate class or a factory method, that does the same as the Scala compiler - just more ugly :)
Lets say I have an array movies = get_movies()
In ruby I often do
movies.map {|movie| movie.poster_image_url } or somesuch.
What can I do that is similar in Java? And by similarly elegant and terse and readable. I know there are a bazillion ways I can do this but if there's a nice way to do this that will make me not want to use Groovy or something let me know. I'm sure Java has some awesome ways to do things like this.
This is my Java code so far using TheMovieDB API Java wrapper from https://github.com/holgerbrandl/themoviedbapi/.
TmdbMovies movies = new TmdbApi(BuildConfig.MOVIEDB_API_KEY).getMovies();
MovieResultsPage results = movies.getPopularMovieList("en", 1);
// The following line is RubyJava and needs to your help!
results.getResults().map {|e| e.getPosterPath() };
// or ... more RubyJava results.getResults().map(&:getPosterPath());
A little more about #map/#collect in Ruby in case you know a lot of Java, but aren't familiar with ruby. http://ruby-doc.org/core-1.9.3/Array.html#method-i-collect
Closest thing I've seen to answering this from some quick browsing so far... https://planet.jboss.org/post/java_developers_should_learn_ruby
These look close, too. http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
So many options: Functional Programming in Java
This is Android as well... Anything good things that are available for Android devs out of the box and make this kind of programming easy? This is a functional programming style, right?
--
After getting replies with really good insights like: 'there is nothing wrong with a for loop' and (basically) 'syntax isn't everything', I am deciding that I will not try to make all my Java look like Ruby! I read this and then imagined an alternate future where 'future me' made a whole bunch of bad style decisions: https://github.com/google/guava/wiki/FunctionalExplained. <-- (A good read. TL;DR 'when you go to preposterous lengths to make your code "a one-liner," the Guava team weeps')
There's the map method on streams which takes a method argument.
collection.stream()
.map(obj -> obj.someMethod())
.collect(Collectors.toList()));
map returns another stream so in order to retrieve the list you have call the collect method.
Too much to explain in a post, but you can visit this link which helped me out a lot:
http://winterbe.com/posts/2014/03/16/java-8-tutorial/
I think (a collections class).foreach() is what you want, requires java8, and often makes use of lambda expressions to implement the class that fulfills the required input for the 'foreach()' method.
http://www.mkyong.com/java8/java-8-foreach-examples/
To address your change to that this is Android, then NO, you WILL NOT get java8 class changes such as .foreach(), you CAN get lambda expressions by making use of the retrolambda android variant. But this only gives you some Java8 'syntax' not 'classes', you won't get access to the Streams classes either.
Inspired by the previous question what is the easiest way to pass a list of integers from java to a frege function? and a comment in the answers by #Ingo, I tried
(Foo/myfregefunction (java.util.List. [1,2,3,4]))
but get (ctor = constructor):
CompilerException java.lang.IllegalArgumentException: No matching ctor found for interface java.util.List
Any ideas? At least java.util.List didn’t yield a ClassCastException; does this mean this is on the right track?
I can send Frege pretty much any Java collection type from Clojure, see Converting Clojure data structures to Java collections.
BTW, using plain (Foo/myfregefunction [1,2,3,4]) instead yields ClassCastException clojure.lang.PersistentVector cannot be cast to free.runtime.Lazy, to which #Ingo points out, “A clojure list is not a frege list.” Similar response when casting as java.util.ArrayList.
On the Frege side, the code is something like
module Foo where
myfregefunction :: [Int] -> Int
-- do something with the list here
Ok, not knowing Clojure, but from the link you gave I take it you need to give the name of an instantiable class (i.e. java.util.ArraList) since java.util.List is just an interface and so cannot be constructed.
For the Frege side, which is the consumer in this case, it suffices to assume the interface.
The whole thing gets a bit complicated, since Frege knows that java lists are mutable. This means that there cannot exist a pure function
∀ s a. Mutable s (List a) → [a]
and every attempt to write such a function in a pure language must fail and will be rejected by the compiler.
Instead, what we need is a ST action to wrap the pure part (in this case, your function myfregefunction). ST is the monad that makes it possible to deal with mutable data. This would go like this:
import Java.Util(List, Iterator) -- java types we need
fromClojure !list =
List.iterator list >>= _.toList >>= pure . myfregefunction
From clojure, you can now call something like (forgive me if I get the clojure syntax wrong (edits welcome)):
(frege.prelude.PreludeBase$TST/run (Foo/fromClojure (java.util.ArrayList. [1,2,3,4])))
This interfacing via Java has two disadvantages, IMHO. For one, we introduce mutability, which the Frege compiler doesn't allow us to ignore, so the interface gets more complicated. And in addition, list data will be duplicated. I don't know how Clojure is doing it, but on the Frege side, at least, there is this code that goes over the iterator and collects the data into a Frege list.
So a better way would be to make Frege aware of what a clojure.lang.PersistentVector is and work directly on the clojure data in Frege. I know of someone who has done it this way with clojure persistent hash maps, so I guess it should be possible to do the same for lists.
(At this point I cannot but point out how valuable it would be to contribute a well thought-out Clojure/Frege interface library!)
Edit: As the self-answer from #0dB suggests, he's about to implement the superior solution mentioned in the previous paragraphs. I encourage everyone to support this noble undertaking with upvotes.
A third way would be to construct the Frege list directly in Clojure.
Based on the answer by #Ingo,
a better way would be to make Frege aware of what a clojure.lang.PersistentVector is and work directly on the clojure data in Frege.
and comments thereto as well as the solution for PersistentMap by Adam Bard, I came up with a working solution:
module foo.Foo where
[EDIT] As Ingo points out, being an instance of ListView gives us list comprehension, head, tail, …
instance ListView PersistentVector
We need to annotate a Clojure class for use in Frege (pure native basically makes the Java methods available to Frege without needing any monad to handle mutability, possible because—in general—data is immutable in Clojure, too):
data PersistentVector a = native clojure.lang.IPersistentVector where
-- methods needed to create new instances
pure native empty clojure.lang.PersistentVector.EMPTY :: PersistentVector a
pure native cons :: PersistentVector a -> a -> PersistentVector a
-- methods needed to transform instance into Frege list
pure native valAt :: PersistentVector a -> Int -> a
pure native length :: PersistentVector a -> Int
Now there follow some functions that are added to this data type for creating a Clojure vector from Frege list or the other way around:
fromList :: [a] -> PersistentVector a
fromList = fold cons empty
toList :: PersistentVector a -> [a]
toList pv = map pv.valAt [0..(pv.length - 1)]
Note my use of the "dot" notation; see the excellent article by #Dierk, The power of the dot.
[EDIT] For ListView (and some fun in Frege with PersistentVector) we need to also implement uncons, null and take (sorry for the quick & dirty solutions here; I will try to fix that soon):
null :: PersistentVector a -> Bool
null x = x.length == 0
uncons :: PersistentVector a -> Maybe (a, PersistentVector a)
uncons x
| null x = Nothing
-- quick & dirty (using fromList, toList); try to use first and rest from Clojure here
| otherwise = Just (x.valAt 0, fromList $ drop 1 $ toList x)
take :: Int -> PersistentVector a -> PersistentVector a
-- quick and dirty (using fromList, toList); improve this
take n = fromList • PreludeList.take n • toList
In my quick & dirty solution above, note the use of PreludeList.take to avoid calling take in the namespace that PersistentVector creates, and how I did not have to prefix fromList, toList, cons and empty.
With this setup (you can leave out uncons, null and take as well as the instance declaration at the top, if you don’t want to do anything with PersistentVector in Frege directly) you can now call a Frege function that takes and returns a list by wrapping it properly:
fromClojure :: PersistentVector a -> PersistentVector a
fromClojure = PersistentVector.fromList • myfregefn • PersistentVector.toList
-- sample (your function here)
myfregefn :: [a] -> [a]
myfregefn = tail
In Clojure we just call (foo.Foo/fromClojure [1 2 3 4]) and get a Clojure vector back with whatever processing myfregefn does (in this example [2 3 4]). If myfregefn returns something that both Clojure and Frege understand (String, Long, …), leave out the PersistentVector.fromList (and fix the type signature). Try both out, tail as above for getting back a list and head for getting back, say, a Long or a String.
For the wrapper and for your Frege function, make sure the type signatures 'match', e. g. PersistentVector a matches [a].
Moving forward: I am doing this because I would like to port some of my Clojure programs to Frege, “a function at a time“. I am sure I will be encountering some more complex data structures that I will have to look into, and, I am still looking into the suggestions by Ingo to improve things.
Google Guava has a predicate that always returns true. Does Java 8 have something similar for its Predicate? I know I could use (foo)->{return true;}, but I want something pre-made, analogous to Collections.emptySet().
There are no built-in always-true and always-false predicates in Java 8. The most concise way to write these is
x -> true
and
x -> false
Compare these to
Predicates.alwaysTrue() // Guava
and finally to an anonymous inner class:
new Predicate<Object>() {
public boolean test(Object x) {
return true;
}
}
Probably the reason that Guava has these built-in predicates is that there is a huge syntactic advantage of a static method call over an anonymous inner class. In Java 8, the lambda syntax is so concise that there is a syntactic disadvantage to writing out a static method call.
That's just a syntactic comparison, though. There is probably a small space advantage if there were a single global always-true predicate, compared to x -> true occurrences spread across multiple classes, each of which would create its own predicate instance. Is this what you're concerned about? The savings didn't seem compelling, which is probably why they weren't added in the first place. But it could be reconsidered for a future release.
UPDATE 2015-04-24
We've considered the addition of a variety of static, named functions such as Predicate.alwaysTrue, Runnable.noop, etc., and we have decided not to add any more in future versions of Java SE.
Certainly there is some value in something that has a name vs. a written-out lambda, but this value is quite small. We expect that people will learn how to read and write x -> true and () -> { } and that their usage will become idiomatic. Even the value of Function.identity() over x -> x is questionable.
There is a tiny performance advantage to reusing an existing function instead of evaluating a written-out lambda, but we expect the usage of these kinds of functions to be so small that such an advantage would be negligible, certainly not worth the API bloat.
Holger also mentioned in comments the possibility of optimizing composed functions such as Predicate.or and such. This was also considered (JDK-8067971) but was deemed somewhat fragile and error-prone, and occurring infrequently enough that it wasn't worth the effort to implement.
See also this Lambda FAQ entry.
In case you are looking for this in Spring framework:
org.springframework.data.util.Predicates supports this.
Predicates.isTrue(), Predicates.isFalse()
Without guava
Boolean.TRUE::booleanValue
I am translating a program from C# to Java. In the C# code, the developer uses Tuple. I need to translate this C# code into Java code. Therefore, does Java have an equivalent variable type to C#'s Tuple?
Due to type erasure, there is no way in Java to have exact mirrors of the various Tuple classes in .NET. However, here is a BSD-licensed implementation of Tuple2 and Tuple3 for Java, which mirror the Tuple<T1, T2> and Tuple<T1, T2, T3> types from .NET.
Tuple.java (static methods to construct tuples with type inference)
Tuple2.java
Tuple3.java
One cool thing you can do in Java but not C# is this:
class Bar extends Foo { }
...
Tuple2<? extends Foo, ? extends Foo> tuple = Tuple.create(new Bar(), new Bar());
In C#, you would have to use casts instead:
Tuple<Foo, Foo> tuple = Tuple.Create((Foo)new Bar(), (Foo)new Bar());
Probably a bit off topic, but have you considered Scala in a JVM environment? It has tuple support + a few other nice features that you might miss from C#.
There seems to be a pretty decent looking Tuple library at https://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/tuple/package-summary.html. Three elements is the largest it can be, but if you need a Tuple larger than three, you should probably give up and define a class.
it's quite old topic, but i will leave this what i recently used during converting C# tuples(Tuple) in Java project - you can simply use org.javatuples lib - https://www.javatuples.org/, which will gives the same behavior to storing data.
Simple example below for people which will lookin for this later:
C#
var tupleCs = new Tuple<string, string, string>("value1","value2","value3");
Console.Writeline(tupleCs.Item1); => value1
Console.Writeline(tupleCs.Item2); => value2
Console.Writeline(tupleCs.Item3); => value3
the same in Java
Triplet tupleJava = new Triplet("value1","value2","value3");
System.out.println(tupleJava.getValue0()); => value1
System.out.println(tupleJava.getValue1()); => value2
System.out.println(tupleJava.getValue2()); => value3
I was in need of Tuple equivalent in my android project as well, but didn't found any native solution in Java. But surprisingly there is Pair.class in android's util which is exact what I was searching for.
So Android developers, who came across this question, use Pair.class in android.util package.
P.S. I'm sad to accept that there are a lot of things that Java is far behind from other languages already.
There might be implementations, but not in the JDK Library as far as I know. See here for an example of your own tuple: Using Pairs or 2-tuples in Java
When you're using Spring Boot with WebFlux it comes with Project Reactor and that provides Tuples classes. The advantage of the Project Reactor implementation is they have a clean way of generating the Tuples using the .of operator
e.g.
Tuples.of("A", 1, myObject);
I usually use it for date ranges as shown in this example to find the starting date of a range given a processing date.
return schedules.stream()
.map(s -> Tuples.of(s.getStartDate(), s.getStopDate().orElse(LocalDate.MAX)))
.filter(range -> (!processingDate.isBefore(range.getT1())) &&
processingDate.isBefore(range.getT2()))
.findAny()
.map(Tuple2::getT1);
There's no need to memorize types like Pair, Triple, Decade, etc.
This is a rather old question, but here is what I ended up developing to be able to use tuples in the post Java 8 world with all of its functional tools and the nicer fluent language: https://github.com/mmnaseri/tuples4j/
It is already available in Maven Central, too, so it is very easy to get a hold of.
At least a 2-tupel exists in Java, right from the beginning: java.util.Map.Entry<K,V>! Ok, it is an interface only …
But since Java 9, there is the static method java.util.Map.entry() that allows the creation of instances of that interface on the fly (in fact, instances of a hidden class implementing that interface, but who cares about that little detail?).
I would not like to use that in the definition of a public API that is not dealing with Collections, but for an internal utility class … why not? The class already exists in the JRE, no additional external dependency, and I can live with the fact that the elements are named "key" and "value" instead of "item1", "item2", …
I am not a C# developer but given the documentation I just looked at about Tuple in C# I can't imagine what you would/could/SHOULD use something like this.
var population = new Tuple<string, int, int, int, int, int, int>(
"New York", 7891957, 7781984,
7894862, 7071639, 7322564, 8008278);
Looking at this code I have no earthly clue what those values represent and can't imagine why you wouldn't use a class.
As I see it, this just represents poor encapsulation.
However, if you want a Tuple in Java, the only one I know of is
Map.Entry<K,V>
And it's really only appropriate for use in Maps