Java потоковый доступ к методам List - PullRequest
1 голос
/ 07 мая 2020

Рассмотрим следующий фрагмент:

List<Integer> list = new ArrayList<>();
int res = list.stream()
    .filter(e-> list.indexOf(e) ==  list.lastIndexOf(e))
    .findFirst()
    .get();
// here I'm creating stream on list, and to access methods of list itself I'm using a reference

Но если я использую Arrays.asList или Arrays.stream для создания потока, как мне получить доступ к этим методам. Я знаю, что сначала могу преобразовать массивы в коллекцию. Но мне нужен более эффективный способ сделать это.

Мне что-то не хватает в потоках? или что-то. Кроме того, посоветуйте мне list.stream, есть ли способ улучшить?

1 Ответ

1 голос
/ 07 мая 2020

Подводя итог обсуждению в комментариях, можно сказать, что может быть способ работы с массивом, но, конечно, без использования методов List:

public class Test {

    private int[] array; // no setter

    public int findNonRepeating(int... arr) {
        this.array = arr;
        return Arrays.stream(array).filter(this::isNonRepeating).findFirst().orElse(-1);
    }

    private boolean isNonRepeating(int a) {
        int fix = IntStream.range(0, array.length)
                           .filter(i -> array[i] == a)
                           .findFirst().orElse(-1);
        int lix = IntStream.range(0, array.length)
                           .map(i -> array.length - i - 1)
                           .filter(i -> array[i] == a)
                           .findFirst().orElse(-1);
        return fix == lix && fix != -1;
    }
}

Хотя, более предпочтительный способ реализовать это выглядит следующим образом:

public int findFirstNonRepeating(int...arr) {
    return Arrays.stream(arr)
                 .boxed()
                 .collect(
                     Collectors.groupingBy(Function.identity(), Collectors.counting()))
                 .entrySet().stream()
                 .filter(e -> e.getValue() == 1)
                 .mapToInt(e -> e.getKey())
                 .findFirst().orElse(-1);
}

обновление

Чтобы максимально использовать возможности List, вы можете расширить ArrayList и указать метод предиката :

public class MyList<T> extends ArrayList<T> {

    public static <T> MyList<T> of(Collection<? extends T> collection) {
        return new MyList<>(collection);
    }

    public MyList() { super(); }
    public MyList(int initialCapacity) { super(initialCapacity); }
    public MyList(Collection<? extends T> collection) { super(collection); }

    public boolean isNonRepeating(T x) {
        return this.indexOf(x) == this.lastIndexOf(x);
    }

    public T findFirstNonRepeating() {
        return stream()
                .filter(this::isNonRepeating)
                .findFirst()
                .orElseThrow(() -> 
                    new NoSuchElementException("This list does not contain non-repeating elements")
                );
    }
}


int x = MyList.of(Arrays.asList(1, 2, 3, 1)).findFirstNonRepeating().intValue();
// x = 2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...