com.hazelcast.org.apache.calcite.linq4j.Ord Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.org.apache.calcite.linq4j;
import com.hazelcast.com.google.common.collect.ImmutableList;
import java.util.AbstractList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.RandomAccess;
import java.util.function.ObjIntConsumer;
/**
* Pair of an element and an ordinal.
*
* @param Element type
*/
public class Ord implements Map.Entry {
public final int i;
public final E e;
/**
* Creates an Ord.
*/
public Ord(int i, E e) {
this.i = i;
this.e = e;
}
/**
* Creates an Ord.
*/
public static Ord of(int n, E e) {
return new Ord<>(n, e);
}
/**
* Creates an iterable of {@code Ord}s over an iterable.
*/
public static Iterable> zip(final Iterable extends E> iterable) {
return () -> zip(iterable.iterator());
}
/**
* Creates an iterator of {@code Ord}s over an iterator.
*/
public static Iterator> zip(final Iterator extends E> iterator) {
return new Iterator>() {
int n = 0;
public boolean hasNext() {
return iterator.hasNext();
}
public Ord next() {
return Ord.of(n++, iterator.next());
}
public void remove() {
iterator.remove();
}
};
}
/**
* Returns a numbered list based on an array.
*/
public static List> zip(final E[] elements) {
return new OrdArrayList<>(elements);
}
/**
* Returns a numbered list.
*/
public static List> zip(final List extends E> elements) {
return elements instanceof RandomAccess
? new OrdRandomAccessList<>(elements)
: new OrdList<>(elements);
}
/**
* Iterates over an array in reverse order.
*
* Given the array ["a", "b", "c"], returns (2, "c") then (1, "b") then
* (0, "a").
*/
public static Iterable> reverse(E... elements) {
return reverse(ImmutableList.copyOf(elements));
}
/**
* Iterates over a list in reverse order.
*
* Given the list ["a", "b", "c"], returns (2, "c") then (1, "b") then
* (0, "a").
*/
public static Iterable> reverse(Iterable extends E> elements) {
final ImmutableList elementList = ImmutableList.copyOf(elements);
return () -> new Iterator>() {
int i = elementList.size() - 1;
public boolean hasNext() {
return i >= 0;
}
public Ord next() {
return Ord.of(i, elementList.get(i--));
}
public void remove() {
throw new UnsupportedOperationException("remove");
}
};
}
public Integer getKey() {
return i;
}
public E getValue() {
return e;
}
public E setValue(E value) {
throw new UnsupportedOperationException();
}
/** Applies an action to every element of an iterable, passing the zero-based
* ordinal of the element to the action.
*
* @see List#forEach(java.util.function.Consumer)
* @see Map#forEach(java.util.function.BiConsumer)
*
* @param iterable Iterable
* @param action The action to be performed for each element
* @param Element type
*/
public static void forEach(Iterable iterable,
ObjIntConsumer super T> action) {
int i = 0;
for (T t : iterable) {
action.accept(t, i++);
}
}
/** Applies an action to every element of an array, passing the zero-based
* ordinal of the element to the action.
*
* @see List#forEach(java.util.function.Consumer)
* @see Map#forEach(java.util.function.BiConsumer)
*
* @param ts Array
* @param action The action to be performed for each element
* @param Element type
*/
public static void forEach(T[] ts,
ObjIntConsumer super T> action) {
for (int i = 0; i < ts.length; i++) {
action.accept(ts[i], i);
}
}
/** List of {@link Ord} backed by a list of elements.
*
* @param element type */
private static class OrdList extends AbstractList> {
private final List extends E> elements;
OrdList(List extends E> elements) {
this.elements = elements;
}
public Ord get(int index) {
return Ord.of(index, elements.get(index));
}
public int size() {
return elements.size();
}
}
/** List of {@link Ord} backed by a random-access list of elements.
*
* @param element type */
private static class OrdRandomAccessList extends OrdList
implements RandomAccess {
OrdRandomAccessList(List extends E> elements) {
super(elements);
}
}
/** List of {@link Ord} backed by an array of elements.
*
* @param element type */
private static class OrdArrayList extends AbstractList>
implements RandomAccess {
private final E[] elements;
OrdArrayList(E[] elements) {
this.elements = elements;
}
@Override public Ord get(int index) {
return Ord.of(index, elements[index]);
}
@Override public int size() {
return elements.length;
}
}
}