Java 8 Lambdas - эквивалент c # OfType

Я изучаю новые функции java 8 сейчас, после 4 лет работы исключительно в мире C #, поэтому лямбды для меня превосходны. Сейчас я изо всех сил пытаюсь найти эквивалент для метода «OfType» в C #.

У меня есть List myNodes, я хочу получить из него List, где Node - это интерфейс, а SpecificNode реализует его.

В C # это будет

IList<INode> myNodes = new List<INodes>(){new SpecificNode(), new OtherNode()}
IList<SpecificNode> specificNodes = myNodes.OfType<SpecificNode>()
12 голосов | спросил Petr Osipov 1 PM00000010000002731 2014, 13:41:27

3 ответа


0

В Java нет точного соответствия для метода .OfType<T>(), но вы можете использовать фильтрацию Java8 особенности:

IList<INode> myNodes = new ArrayList<INode>();
myNodes.add(new SpecificNode());
myNodes.add(new OtherNode());

List<SpecificNode> filteredList = myNodes.stream()
                                         .filter(x -> x instanceof SpecificNode)
                                         .map(n -> (SpecificNode) n)
                                         .collect(Collectors.toList());

Если вы хотите получить явное приведение, вы можете сделать:

List<SpecificNode> filteredList = myNodes.stream()
                                             .filter(SpecificNode.class::isInstance)
                                             .map(SpecificNode.class::cast)
                                             .collect(Collectors.toList());
ответил Konstantin Yovkov 1 PM00000010000001331 2014, 13:47:13
0

У меня была такая же проблема. Это то, что я придумал, но поскольку java не использует методы расширения (возможно, еще через 10 лет?), Это статический метод. Это использует потоковый API, хотя нет особой причины, по которой вы должны сделать это. Те же самые базовые проверки будут прекрасно работать в цикле for с предварительно выделенным списком ArrayList.

@SuppressWarnings("unchecked")
private static <T> List<T> ofType(Class<?> out, List<Object> list) {
    return list.stream().filter(x -> out.isAssignableFrom(x.getClass()))
               .map(x -> (T) x) // unchecked
               .collect(Collectors.toList());
}

// fyi this code uses "boon" library
List<Object> objlist = list("ABC", 3, "def", -30.39); 
puts("strings=", ofType(String.class, objlist));  // strings= [ABC, def] 
puts("integers=", ofType(Integer.class, objlist)); // integers= [3]

Вот версия, которая не использует потоки. Он работает точно так же, но некоторые забавы с потоками заключаются в том, что ... вы можете передавать их в потоковом режиме, если это ваш тип вещей. Я не нахожу это полезным очень часто, за исключением таких помощников.

private static <T> List<T> ofType(Class<?> out, List<Object> list) {
    List<T> outList = new ArrayList<T>(list.size());
    for(Object o : list) {
        if ( out.isAssignableFrom(o.getClass())) {
            outList.add((T)o);
        }
    }
    return outList;
}
ответил Andrew Backer 26 AM000000100000003531 2014, 10:31:35
0

Вы можете создать функцию, содержащую конвейер Stream, который уменьшает ее вызов.

    Function<List<INode>,List<SpecificNode>> ofSub =
       bl -> bl.stream()
               .filter(x -> x instanceof SpecificNode)
               .map(n -> (SpecificNode) n)
               .collect(Collectors.toList());

Например:

    for( SpecificNode s: ofSub.apply( myNodes ) ){
         //...
    }
ответил laune 1 PM00000030000000131 2014, 15:23:01

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132