Java8 でも動くことを前提にする。(まだ Java8 を使う企業が多いからだ)
配列
equals で比較できる場合
public static <T> boolean matchElements(T[] ary) {
if (ary.length < 2) return true;
for(int i=0, j=1; j < ary.length; i++, j++) {
if (!ary[i].equals(ary[j])) return false;
}
return true;
}
比較を BiPredicate にすることで equals と違う方法で判定する
public static <T> boolean matchElements(T[] ary, BiPredicate<T, T> m) {
if (ary.length < 2) return true;
for(int i=0, j=1; j < ary.length; i++, j++) {
if (!m.test(ary[i], ary[j])) return false;
}
return true;
}
null がある場合、↑の BiPredicate を記述する中で対処すれば良いのだが、
あえて null の場合に BiPredicate に渡すものを定義するなら、
public static <T> boolean matchElements(T[] ary, BiPredicate<T, T> m, Supplier<T> nsup) {
if (ary.length < 2) return true;
for(int i=0, j=1; j < ary.length; i++, j++) {
if (!m.test(Optional.ofNullable(ary[i]).orElse(nsup.get())
, Optional.ofNullable(ary[j]).orElse(nsup.get()))) return false;
}
return true;
}
List で、イテレータを使う場合、
public static <T> boolean matchElements(List<T> list, BiPredicate<T, T> p) {
for(ListIterator<T> it = list.listIterator(); it.hasNext();){
T t = it.next();
if (it.hasPrevious()){
T u = it.previous();
if (it.hasPrevious()){
u = it.previous();
if (!p.test(u, t)) return false;
it.next();
}
it.next();
}
}
return true;
}
null の場合に BiPredicate に渡すものを定義するなら、
public static <T> boolean matchElements(List<T> list, BiPredicate<T, T> p, Supplier<T> nsup) {
for(ListIterator<T> it = list.listIterator(); it.hasNext();){
T t = it.next();
if (it.hasPrevious()){
T u = it.previous();
if (it.hasPrevious()){
u = it.previous();
if (!p.test(Optional.ofNullable(u).orElse(nsup.get())
, Optional.ofNullable(t).orElse(nsup.get()))) return false;
it.next();
}
it.next();
}
}
return true;
}
Stream で処理、
Collectors.groupingBy でカウントして調べる
public static <T, K> boolean matchElements(Collection<T> c, Function<T, K> m) {
return c.stream().collect(Collectors.groupingBy(t->m.apply(t), Collectors.counting())).size()==1;
}
但し、これはFunction が null を返してはならない。
要素が null の場合を考慮していないので、null を除くなら
public static <T, K> boolean matchElements(Collection<T> c, Function<T, K> m) {
return c.stream().filter(t->t != null)
.collect(Collectors.groupingBy(t->m.apply(t), Collectors.counting())).size()==1;
}
そもそも、null の場合、別の値に置き換えて Function を実行させれば、Function の記述も楽になる。
public static <T, K> boolean matchElements(Collection<T> c, Function<T, K> m, Supplier<T> nullTemp) {
return c.stream().map(t->Optional.ofNullable(t).orElse(nullTemp.get()))
.collect(Collectors.groupingBy(t->m.apply(t), Collectors.counting())).size()==1;
}