diff --git a/src/org/openstreetmap/josm/tools/Predicate.java b/src/org/openstreetmap/josm/tools/Predicate.java
index 969300c..7886e6e 100644
--- a/src/org/openstreetmap/josm/tools/Predicate.java
+++ b/src/org/openstreetmap/josm/tools/Predicate.java
@@ -6,8 +6,11 @@ package org.openstreetmap.josm.tools;
  *
  * @param <T> The objects type
  * @since 3177
+ * @deprecated Use {@link java.util.function.Predicate} instead.
  */
-public interface Predicate<T> {
+@Deprecated
+@FunctionalInterface
+public interface Predicate<T> extends java.util.function.Predicate<T> {
 
     /**
      * Determines whether the object passes the test or not
@@ -15,4 +18,9 @@ public interface Predicate<T> {
      * @return {@code true} if the object passes the test, {@code false} otherwise
      */
     boolean evaluate(T object);
+
+    @Override
+    default boolean test(T t) {
+        return evaluate(t);
+    }
 }
diff --git a/src/org/openstreetmap/josm/tools/Predicates.java b/src/org/openstreetmap/josm/tools/Predicates.java
index 5d072c3..8041594 100644
--- a/src/org/openstreetmap/josm/tools/Predicates.java
+++ b/src/org/openstreetmap/josm/tools/Predicates.java
@@ -22,12 +22,7 @@ public final class Predicates {
      * @since 10040
      */
     public static <T> Predicate<T> alwaysTrue() {
-        return new Predicate<T>() {
-            @Override
-            public boolean evaluate(T object) {
-                return true;
-            }
-        };
+        return o -> true;
     }
 
     /**
@@ -37,12 +32,7 @@ public final class Predicates {
      * @since 10040
      */
     public static <T> Predicate<T> alwaysFalse() {
-        return new Predicate<T>() {
-            @Override
-            public boolean evaluate(T object) {
-                return false;
-            }
-        };
+        return o -> false;
     }
 
     /**
@@ -50,14 +40,11 @@ public final class Predicates {
      * @param <T> type of items
      * @param predicate the predicate to negate
      * @return the negation of {@code predicate}
+     * @deprecated Use {@link java.util.function.Predicate#negate()}
      */
+    @Deprecated
     public static <T> Predicate<T> not(final Predicate<T> predicate) {
-        return new Predicate<T>() {
-            @Override
-            public boolean evaluate(T obj) {
-                return !predicate.evaluate(obj);
-            }
-        };
+        return obj -> !predicate.evaluate(obj);
     }
 
     /**
@@ -67,12 +54,7 @@ public final class Predicates {
      * @return a {@link Predicate} executing {@link Objects#equals}
      */
     public static <T> Predicate<T> equalTo(final T ref) {
-        return new Predicate<T>() {
-            @Override
-            public boolean evaluate(T obj) {
-                return Objects.equals(obj, ref);
-            }
-        };
+        return obj -> Objects.equals(obj, ref);
     }
 
     /**
@@ -84,12 +66,7 @@ public final class Predicates {
      */
     public static <T> Predicate<T> isOfClass(final Class<? extends T> clazz) {
         CheckParameterUtil.ensureParameterNotNull(clazz, "clazz");
-        return new Predicate<T>() {
-            @Override
-            public boolean evaluate(T obj) {
-                return obj != null && obj.getClass() == clazz;
-            }
-        };
+        return obj -> obj != null && obj.getClass() == clazz;
     }
 
     /**
@@ -102,12 +79,7 @@ public final class Predicates {
      */
     public static <T> Predicate<T> isInstanceOf(final Class<? extends T> clazz) {
         CheckParameterUtil.ensureParameterNotNull(clazz, "clazz");
-        return new Predicate<T>() {
-            @Override
-            public boolean evaluate(T o) {
-                return clazz.isInstance(o);
-            }
-        };
+        return o -> clazz.isInstance(o);
     }
 
     /**
@@ -116,12 +88,7 @@ public final class Predicates {
      * @return a {@link Predicate} executing {@link Pattern#matcher(CharSequence)} and {@link java.util.regex.Matcher#matches}
      */
     public static Predicate<String> stringMatchesPattern(final Pattern pattern) {
-        return new Predicate<String>() {
-            @Override
-            public boolean evaluate(String string) {
-                return pattern.matcher(string).matches();
-            }
-        };
+        return string -> pattern.matcher(string).matches();
     }
 
     /**
@@ -130,12 +97,7 @@ public final class Predicates {
      * @return a {@link Predicate} executing {@link Pattern#matcher(CharSequence)} and {@link java.util.regex.Matcher#find}
      */
     public static Predicate<String> stringContainsPattern(final Pattern pattern) {
-        return new Predicate<String>() {
-            @Override
-            public boolean evaluate(String string) {
-                return pattern.matcher(string).find();
-            }
-        };
+        return string -> pattern.matcher(string).find();
     }
 
     /**
@@ -144,12 +106,7 @@ public final class Predicates {
      * @return a {@link Predicate} executing {@link String#contains(CharSequence)}
      */
     public static Predicate<String> stringContains(final String pattern) {
-        return new Predicate<String>() {
-            @Override
-            public boolean evaluate(String string) {
-                return string.contains(pattern);
-            }
-        };
+        return string -> string.contains(pattern);
     }
 
     /**
@@ -159,12 +116,7 @@ public final class Predicates {
      * @return a {@link Predicate} executing {@link OsmPrimitive#hasTag(String, String...)}
      */
     public static Predicate<OsmPrimitive> hasTag(final String key, final String... values) {
-        return new Predicate<OsmPrimitive>() {
-            @Override
-            public boolean evaluate(OsmPrimitive p) {
-                return p.hasTag(key, values);
-            }
-        };
+        return string -> p.hasTag(key, values);
     }
 
     /**
@@ -173,12 +125,7 @@ public final class Predicates {
      * @return a {@link Predicate} executing {@link OsmPrimitive#hasKey(String)}
      */
     public static Predicate<OsmPrimitive> hasKey(final String key) {
-        return new Predicate<OsmPrimitive>() {
-            @Override
-            public boolean evaluate(OsmPrimitive p) {
-                return p.hasKey(key);
-            }
-        };
+        return p -> p.hasKey(key);
     }
 
     /**
@@ -188,12 +135,7 @@ public final class Predicates {
      * @return a {@link Predicate} executing {@link Collection#contains(Object)}
      */
     public static <T> Predicate<T> inCollection(final Collection<? extends T> target) {
-        return new Predicate<T>() {
-            @Override
-            public boolean evaluate(T object) {
-                return target.contains(object);
-            }
-        };
+        return object -> target.contains(object);
     }
 
     /**
@@ -202,12 +144,7 @@ public final class Predicates {
      * @return a {@link Predicate} testing whether objects are {@code null}
      */
     public static <T> Predicate<T> isNull() {
-        return new Predicate<T>() {
-            @Override
-            public boolean evaluate(T object) {
-                return object == null;
-            }
-        };
+        return object -> object == null;
     }
 
 }
diff --git a/src/org/openstreetmap/josm/tools/SubclassFilteredCollection.java b/src/org/openstreetmap/josm/tools/SubclassFilteredCollection.java
index ed6531a..263857d 100644
--- a/src/org/openstreetmap/josm/tools/SubclassFilteredCollection.java
+++ b/src/org/openstreetmap/josm/tools/SubclassFilteredCollection.java
@@ -11,6 +11,8 @@ import java.util.NoSuchElementException;
  * (read-only collection, but elements can be changed, of course)
  * Lets you iterate through those elements of a given collection that satisfy a
  * certain condition (imposed by a predicate).
+ * <p>
+ * The behaviour of this class is undefined if the underlying collection is changed.
  * @param <S> element type of the underlying collection
  * @param <T> element type of filtered collection (and subclass of S). The predicate
  *      must accept only objects of type T.
@@ -19,7 +21,7 @@ import java.util.NoSuchElementException;
 public class SubclassFilteredCollection<S, T extends S> extends AbstractCollection<T> {
 
     private final Collection<? extends S> collection;
-    private final Predicate<? super S> predicate;
+    private final java.util.function.Predicate<? super S> predicate;
     private int size = -1;
 
     private class FilterIterator implements Iterator<T> {
@@ -35,7 +37,7 @@ public class SubclassFilteredCollection<S, T extends S> extends AbstractCollecti
             if (current == null) {
                 while (iterator.hasNext()) {
                     current = iterator.next();
-                    if (predicate.evaluate(current))
+                    if (predicate.test(current))
                         return;
                 }
                 current = null;
@@ -69,8 +71,20 @@ public class SubclassFilteredCollection<S, T extends S> extends AbstractCollecti
      * Constructs a new {@code SubclassFilteredCollection}.
      * @param collection The base collection to filter
      * @param predicate The predicate to use as filter
+     * @deprecated Use java predicates instead.
      */
+    @Deprecated
     public SubclassFilteredCollection(Collection<? extends S> collection, Predicate<? super S> predicate) {
+        this(collection, (java.util.function.Predicate<? super S>) predicate);
+    }
+
+    /**
+     * Constructs a new {@code SubclassFilteredCollection}.
+     * @param collection The base collection to filter
+     * @param predicate The predicate to use as filter
+     * @see #filter(Collection, java.util.function.Predicate) for an alternative way to construct this.
+     */
+    public SubclassFilteredCollection(Collection<? extends S> collection, java.util.function.Predicate<? super S> predicate) {
         this.collection = collection;
         this.predicate = predicate;
     }
@@ -97,4 +111,15 @@ public class SubclassFilteredCollection<S, T extends S> extends AbstractCollecti
     public boolean isEmpty() {
         return !iterator().hasNext();
     }
+
+    /**
+     * Create a new filtered collection without any constraints on the predicate type.
+     * @param <T> The collection type.
+     * @param collection The collection to filter.
+     * @param predicate The predicate to filter for.
+     * @return The filtered collection. It is a Collection<T>.
+     */
+    public static <T> SubclassFilteredCollection<T, T> filter(Collection<T> collection, java.util.function.Predicate<T> predicate) {
+        return new SubclassFilteredCollection<T, T>(collection, predicate);
+    }
 }
diff --git a/src/org/openstreetmap/josm/tools/Utils.java b/src/org/openstreetmap/josm/tools/Utils.java
index 10fc99e..1f76a84 100644
--- a/src/org/openstreetmap/josm/tools/Utils.java
+++ b/src/org/openstreetmap/josm/tools/Utils.java
@@ -57,6 +57,7 @@ import java.util.concurrent.ThreadFactory;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 import java.util.zip.GZIPInputStream;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
@@ -101,6 +102,8 @@ public final class Utils {
 
     /**
      * Tests whether {@code predicate} applies to at least one element from {@code collection}.
+     * <p>
+     * Note: you can use {@link Stream#anyMatch(java.util.function.Predicate)} instead.
      * @param <T> type of items
      * @param collection the collection
      * @param predicate the predicate
@@ -117,6 +120,8 @@ public final class Utils {
 
     /**
      * Tests whether {@code predicate} applies to all elements from {@code collection}.
+     * <p>
+     * Note: you can use {@link Stream#allMatch(java.util.function.Predicate)} instead.
      * @param <T> type of items
      * @param collection the collection
      * @param predicate the predicate
@@ -171,7 +176,9 @@ public final class Utils {
      * @param collection The collection to filter.
      * @param predicate The predicate to filter for.
      * @return The new {@link FilteredCollection}
+     * @deprecated Use java predicates and {@link SubclassFilteredCollection#filter(Collection, java.util.function.Predicate)} instead.
      */
+    @Deprecated
     @SuppressWarnings("unused")
     public static <T> Collection<T> filter(Collection<? extends T> collection, Predicate<? super T> predicate) {
         // Diamond operator does not work with Java 9 here
@@ -780,7 +787,10 @@ public final class Utils {
      * returns objects of {@code B}.
      * @param <A> class of input objects
      * @param <B> class of transformed objects
+     *
+     * @deprecated Use java.util.function.Function instead.
      */
+    @Deprecated
     public interface Function<A, B> {
 
         /**
