Reputation:
Consider the following snippet
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
But If I am using Arrays.asList
or Arrays.stream
to create a stream How can I access these methods.
I know I can First convert the Arrays to Collection. But I want a more efficient way to do this.
Am I missing something about streams? or Something. Also, suggest to me about the list.stream
is there any way to improve?
Upvotes: 1
Views: 226
Reputation: 19565
To summarize discussion in comments, there could be a way to work with array, but of course without using List methods:
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;
}
}
Though, more preferable way to implement this seems to be this:
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);
}
update
In order to reuse List
functionality as much as possible, you may extend ArrayList
and provide predicate method:
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) {
int fx = this.indexOf(x);
return fx > -1 && fx == 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
Upvotes: 1