3 ms·
Not the guy that you were asking but Trivial example: public static void assertIsSuperset(Collection<Object> superSet, Collection<Object> actualSet) { fi
by somerandomqaguy 7y ago
Not the guy that you were asking but Trivial example:
public static void assertIsSuperset(Collection<Object> superSet, Collection<Object> actualSet) {
final List<Object> missing;
missing = actualSet.stream().filter(x -> !superSet.contains(x)).collect(Collectors.toList());
if (missing.size() != 0) {
/* Imagine some more verbose exception creation here, which is why we caught it in a list*/
}
}
The lambda is in the creation of 'missing':
filter(x -> !superSet.contains(x))
A lot collections in Java 8 brought in a stream method which has some functional esqe methods. Filter is one of them, and if you look at filter's method signature:
public interface Stream<T> extends BaseStream<T, Stream<T>> {
/**
* Returns a stream consisting of the elements of this stream that match
* the given predicate.
*
* <p>This is an <a href="package-summary.html#StreamOps">intermediate
* operation</a>.
*
* @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
* <a href="package-summary.html#Statelessness">stateless</a>
* predicate to apply to each element to determine if it
* should be included
* @return the new stream
*/
Stream<T> filter(Predicate<? super T> predicate);
[SNIP!]
}
Predicate is an interface that has one method: 'public boolean test(T t);'. The lambda that I created conforms to that single method; accepting the generic object (x) and returning the boolean tested by '!superSet.contain(x)' The other way I've seen them used is to implement an anonymous version of an interface.
- WAHa_06x36 7y agoThat still seems very clunky and also very inefficient compared to what I'd do in Swift: func isSuperset<Type: Equatable>(superSet: Set<Type>, actualSet: Set<Type>) -> Bool { return actualSet.contains(where: { !superSet.contains($0) }) } What is all the noise about "collect"? Why allocate a while new list? What's with the "final"? And why do I have to type out obvious types in 2019?
- aardvark179 7y agoYeah, the collect isn't really needed, you could easily use a reduce to calculate the value.
- sbov 7y agoThe equivalent expression in Java would actually be this: actualSet.stream().anyMatch(x -> !superSet.contains(x));
- somerandomqaguy 7y agoBecause you're doing something entirely different, I'm asserting, you're testing. The equivalent java code would be: return superSet.containsAll(actualSet); But a straight up boolean doesn't tell me what is missing, only that something is missing. I snipped out the bit about creating a more verbose exception creation because it wasn't really needed for the example: if (missing.size() != 0) { final StringBuilder builder; builder = new StringBuilder(); builder.append("Missing item found: [ "); builder.append(String.join(",", missing.stream().map(x -> x.toString())).collect(Collectors.toList()))); builder.append(" ]"); throw new IllegalStateException(builder.toString()); } Keep in mind that the objects that this method was written for actually implement human readable toString methods. > What's with the "final"? Habit that I forced on myself. But it's not a bad habit to get into. In theory methods are supposed to be short and readable but reality often ends up being that in the fury of writing under looming deadlines you can have horrifically long methods that do many things. And I've seen more then a few times someone reusing variable names badly. Using final when possible is just a way for someone to be able to look at the code, see the variable name and be able to know that what it says is what it is. >And why do I have to type out obvious types in 2019 Because types aren't always obvious. That's a list, meaning that you can have duplicated items and that order matters. What if my 'list' was actually a set, in which order was not guaranteed? What about if you're trying to integrate this with multiples teams scattered across the world that don't speak English on a code base that's about 500,000 lines of code? Or when you walk away for 2 or 3 years and then have to come back to a method that's not as small and trivial as the given example? What about the next poor sap that has it dumped in his lap? I know it seems stupid in the short run, and if you've got something small or something that probably wont' be relevant in a year or two, and I'd agree with you if that's the case. But but if you've got a code base that needs to be communicated to other people, then typing is a good way of handling that communication without having to write extra documentation.
- pjmlp 7y agoExcept that is a Pyrrhic victory, as Swift is quite useless outside Apple platforms. Linux support is still WIP, Windows nowhere to be seen, and everything else is not supported at all.
- ngrilly 7y agoThanks! I guess your example could be simplified further with the var keyword: public static void assertIsSuperset(Collection<Object> superSet, Collection<Object> actualSet) { var missing = actualSet.stream().filter(x -> !superSet.contains(x)).collect(Collectors.toList()); if (missing.size() != 0) { /* Imagine some more verbose exception creation here, which is why we caught it in a list*/ } }