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; }