com.gs.collections.impl.string.immutable.CodePointAdapter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gs-collections Show documentation
Show all versions of gs-collections Show documentation
GS Collections is a collections framework for Java. It has JDK-compatible List, Set and Map
implementations with a rich API and set of utility classes that work with any JDK compatible Collections,
Arrays, Maps or Strings. The iteration protocol was inspired by the Smalltalk collection framework.
/*
* Copyright 2015 Goldman Sachs.
*
* Licensed 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.gs.collections.impl.string.immutable;
import java.io.IOException;
import java.io.Serializable;
import java.util.NoSuchElementException;
import com.gs.collections.api.IntIterable;
import com.gs.collections.api.LazyIntIterable;
import com.gs.collections.api.bag.primitive.MutableIntBag;
import com.gs.collections.api.block.function.primitive.IntToIntFunction;
import com.gs.collections.api.block.function.primitive.IntToObjectFunction;
import com.gs.collections.api.block.function.primitive.ObjectIntIntToObjectFunction;
import com.gs.collections.api.block.function.primitive.ObjectIntToObjectFunction;
import com.gs.collections.api.block.predicate.primitive.IntPredicate;
import com.gs.collections.api.block.procedure.primitive.IntIntProcedure;
import com.gs.collections.api.block.procedure.primitive.IntProcedure;
import com.gs.collections.api.iterator.IntIterator;
import com.gs.collections.api.list.ImmutableList;
import com.gs.collections.api.list.primitive.ImmutableIntList;
import com.gs.collections.api.list.primitive.IntList;
import com.gs.collections.api.list.primitive.MutableIntList;
import com.gs.collections.api.set.primitive.MutableIntSet;
import com.gs.collections.impl.bag.mutable.primitive.IntHashBag;
import com.gs.collections.impl.lazy.primitive.ReverseIntIterable;
import com.gs.collections.impl.list.mutable.FastList;
import com.gs.collections.impl.list.mutable.primitive.IntArrayList;
import com.gs.collections.impl.primitive.AbstractIntIterable;
import com.gs.collections.impl.set.mutable.primitive.IntHashSet;
/**
* Calculates and provides the code points stored in a String as an ImmutableIntList. This is a cleaner more OO way of
* providing many of the iterable protocols available in StringIterate for code points.
*
* @since 7.0
*/
public class CodePointAdapter extends AbstractIntIterable implements CharSequence, ImmutableIntList, Serializable
{
private static final long serialVersionUID = 1L;
private final String adapted;
public CodePointAdapter(String value)
{
this.adapted = value;
}
public static CodePointAdapter adapt(String value)
{
return new CodePointAdapter(value);
}
public static CodePointAdapter from(int... codePoints)
{
StringBuilder builder = new StringBuilder();
for (int i = 0; i < codePoints.length; i++)
{
int codePoint = codePoints[i];
builder.appendCodePoint(codePoint);
}
return new CodePointAdapter(builder.toString());
}
public static CodePointAdapter from(IntIterable iterable)
{
if (iterable instanceof CodePointAdapter)
{
return new CodePointAdapter(iterable.toString());
}
StringBuilder builder = iterable.injectInto(new StringBuilder(), new ObjectIntToObjectFunction()
{
public StringBuilder valueOf(StringBuilder builder, int value)
{
return builder.appendCodePoint(value);
}
});
return new CodePointAdapter(builder.toString());
}
public char charAt(int index)
{
return this.adapted.charAt(index);
}
public int length()
{
return this.adapted.length();
}
public String subSequence(int start, int end)
{
return this.adapted.substring(start, end);
}
public StringBuilder toStringBuilder()
{
return new StringBuilder(this.adapted);
}
@Override
public String toString()
{
return this.adapted;
}
public IntIterator intIterator()
{
return new InternalIntIterator();
}
public int[] toArray()
{
return this.toList().toArray();
}
public boolean contains(int expected)
{
int length = this.adapted.length();
for (int i = 0; i < length; )
{
int codePoint = this.adapted.codePointAt(i);
if (expected == codePoint)
{
return true;
}
i += Character.charCount(codePoint);
}
return false;
}
public void forEach(IntProcedure procedure)
{
this.each(procedure);
}
public void each(IntProcedure procedure)
{
int length = this.adapted.length();
for (int i = 0; i < length; )
{
int codePoint = this.adapted.codePointAt(i);
procedure.value(codePoint);
i += Character.charCount(codePoint);
}
}
public CodePointAdapter distinct()
{
StringBuilder builder = new StringBuilder();
IntHashSet seenSoFar = new IntHashSet();
int length = this.adapted.length();
for (int i = 0; i < length; )
{
int codePoint = this.adapted.codePointAt(i);
if (seenSoFar.add(codePoint))
{
builder.appendCodePoint(codePoint);
}
i += Character.charCount(codePoint);
}
return new CodePointAdapter(builder.toString());
}
public CodePointAdapter newWith(int element)
{
StringBuilder builder = new StringBuilder(this.adapted);
builder.appendCodePoint(element);
return new CodePointAdapter(builder.toString());
}
public CodePointAdapter newWithout(int element)
{
StringBuilder builder = new StringBuilder();
int indexToRemove = this.indexOf(element);
if (indexToRemove < 0)
{
return this;
}
int currentIndex = 0;
int length = this.adapted.length();
for (int i = 0; i < length; )
{
int codePoint = this.adapted.codePointAt(i);
if (currentIndex++ != indexToRemove)
{
builder.appendCodePoint(codePoint);
}
i += Character.charCount(codePoint);
}
return new CodePointAdapter(builder.toString());
}
public CodePointAdapter newWithAll(IntIterable elements)
{
final StringBuilder builder = new StringBuilder(this.adapted);
elements.each(new IntProcedure()
{
public void value(int each)
{
builder.appendCodePoint(each);
}
});
return new CodePointAdapter(builder.toString());
}
public CodePointAdapter newWithoutAll(IntIterable elements)
{
MutableIntList mutableIntList = this.toList();
mutableIntList.removeAll(elements);
return CodePointAdapter.from(mutableIntList.toArray());
}
public CodePointAdapter toReversed()
{
final StringBuilder builder = new StringBuilder();
LazyIntIterable reversed = this.asReversed();
reversed.each(new IntProcedure()
{
public void value(int codePoint)
{
builder.appendCodePoint(codePoint);
}
});
return new CodePointAdapter(builder.toString());
}
public ImmutableIntList subList(int fromIndex, int toIndex)
{
throw new UnsupportedOperationException("SubList is not implemented on CodePointAdapter");
}
public int get(int index)
{
int currentIndex = 0;
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (index == currentIndex)
{
return codePoint;
}
i += Character.charCount(codePoint);
currentIndex++;
}
throw new IndexOutOfBoundsException("Index out of bounds");
}
public long dotProduct(IntList list)
{
throw new UnsupportedOperationException("DotProduct is not implemented on CodePointAdapter");
}
public int binarySearch(int value)
{
throw new UnsupportedOperationException("BinarySearch is not implemented on CodePointAdapter");
}
public int lastIndexOf(int value)
{
for (int i = this.size() - 1; i >= 0; i--)
{
int codePoint = this.get(i);
if (codePoint == value)
{
return i;
}
}
return -1;
}
public ImmutableIntList toImmutable()
{
return this;
}
public int getLast()
{
return this.get(this.size() - 1);
}
public LazyIntIterable asReversed()
{
return ReverseIntIterable.adapt(this);
}
public T injectIntoWithIndex(T injectedValue, ObjectIntIntToObjectFunction super T, ? extends T> function)
{
T result = injectedValue;
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
result = function.valueOf(result, codePoint, i);
i += Character.charCount(codePoint);
}
return result;
}
public int getFirst()
{
return this.get(0);
}
public int indexOf(int value)
{
int currentIndex = 0;
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (codePoint == value)
{
return currentIndex;
}
i += Character.charCount(codePoint);
currentIndex++;
}
return -1;
}
public void forEachWithIndex(IntIntProcedure procedure)
{
int currentIndex = 0;
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
procedure.value(codePoint, currentIndex);
i += Character.charCount(codePoint);
currentIndex++;
}
}
public CodePointAdapter select(IntPredicate predicate)
{
StringBuilder selected = new StringBuilder();
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (predicate.accept(codePoint))
{
selected.appendCodePoint(codePoint);
}
i += Character.charCount(codePoint);
}
return new CodePointAdapter(selected.toString());
}
public CodePointAdapter reject(IntPredicate predicate)
{
StringBuilder rejected = new StringBuilder();
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (!predicate.accept(codePoint))
{
rejected.appendCodePoint(codePoint);
}
i += Character.charCount(codePoint);
}
return new CodePointAdapter(rejected.toString());
}
public ImmutableList collect(IntToObjectFunction extends V> function)
{
FastList list = FastList.newList(this.adapted.length());
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
list.add(function.valueOf(codePoint));
i += Character.charCount(codePoint);
}
return list.toImmutable();
}
public CodePointAdapter collectInt(IntToIntFunction function)
{
StringBuilder collected = new StringBuilder(this.length());
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
collected.appendCodePoint(function.valueOf(codePoint));
i += Character.charCount(codePoint);
}
return CodePointAdapter.adapt(collected.toString());
}
public int detectIfNone(IntPredicate predicate, int ifNone)
{
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (predicate.accept(codePoint))
{
return codePoint;
}
i += Character.charCount(codePoint);
}
return ifNone;
}
public int count(IntPredicate predicate)
{
int count = 0;
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (predicate.accept(codePoint))
{
count++;
}
i += Character.charCount(codePoint);
}
return count;
}
public boolean anySatisfy(IntPredicate predicate)
{
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (predicate.accept(codePoint))
{
return true;
}
i += Character.charCount(codePoint);
}
return false;
}
public boolean allSatisfy(IntPredicate predicate)
{
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (!predicate.accept(codePoint))
{
return false;
}
i += Character.charCount(codePoint);
}
return true;
}
public boolean noneSatisfy(IntPredicate predicate)
{
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (predicate.accept(codePoint))
{
return false;
}
i += Character.charCount(codePoint);
}
return true;
}
@Override
public MutableIntList toList()
{
IntArrayList list = new IntArrayList(this.adapted.length());
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
list.add(codePoint);
i += Character.charCount(codePoint);
}
return list;
}
@Override
public MutableIntSet toSet()
{
IntHashSet set = new IntHashSet(this.adapted.length());
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
set.add(codePoint);
i += Character.charCount(codePoint);
}
return set;
}
@Override
public MutableIntBag toBag()
{
IntHashBag bag = new IntHashBag(this.adapted.length());
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
bag.add(codePoint);
i += Character.charCount(codePoint);
}
return bag;
}
public T injectInto(T injectedValue, ObjectIntToObjectFunction super T, ? extends T> function)
{
T result = injectedValue;
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
result = function.valueOf(result, codePoint);
i += Character.charCount(codePoint);
}
return result;
}
public long sum()
{
long sum = 0;
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
sum += codePoint;
i += Character.charCount(codePoint);
}
return sum;
}
public int max()
{
if (this.isEmpty())
{
throw new NoSuchElementException();
}
int max = this.get(0);
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (max < codePoint)
{
max = codePoint;
}
i += Character.charCount(codePoint);
}
return max;
}
public int min()
{
if (this.isEmpty())
{
throw new NoSuchElementException();
}
int min = this.get(0);
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (codePoint < min)
{
min = codePoint;
}
i += Character.charCount(codePoint);
}
return min;
}
public int size()
{
int size = 0;
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
i += Character.charCount(codePoint);
size++;
}
return size;
}
public void appendString(Appendable appendable, String start, String separator, String end)
{
try
{
appendable.append(start);
for (int i = 0; i < this.adapted.length(); )
{
if (i > 0)
{
appendable.append(separator);
}
int codePoint = this.adapted.codePointAt(i);
if (appendable instanceof StringBuilder)
{
((StringBuilder) appendable).appendCodePoint(codePoint);
}
else if (appendable instanceof StringBuffer)
{
((StringBuffer) appendable).appendCodePoint(codePoint);
}
else
{
char[] chars = Character.toChars(codePoint);
for (int j = 0; j < chars.length; j++)
{
appendable.append(chars[j]);
}
}
i += Character.charCount(codePoint);
}
appendable.append(end);
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
@Override
public boolean equals(Object otherList)
{
if (otherList == this)
{
return true;
}
if (otherList instanceof CodePointAdapter)
{
return this.equalsCodePointAdapter((CodePointAdapter) otherList);
}
if (otherList instanceof IntList)
{
return this.equalsIntList((IntList) otherList);
}
return false;
}
public boolean equalsIntList(IntList list)
{
int size = 0;
for (int i = 0; i < this.adapted.length(); )
{
size++;
int codePoint = this.adapted.codePointAt(i);
if (size > list.size() || codePoint != list.get(size - 1))
{
return false;
}
i += Character.charCount(codePoint);
}
if (size < list.size())
{
return false;
}
return true;
}
private boolean equalsCodePointAdapter(CodePointAdapter adapter)
{
if (this.adapted.length() != adapter.adapted.length())
{
return false;
}
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
if (codePoint != adapter.adapted.codePointAt(i))
{
return false;
}
i += Character.charCount(codePoint);
}
return true;
}
@Override
public int hashCode()
{
int hashCode = 1;
for (int i = 0; i < this.adapted.length(); )
{
int codePoint = this.adapted.codePointAt(i);
hashCode = 31 * hashCode + codePoint;
i += Character.charCount(codePoint);
}
return hashCode;
}
private class InternalIntIterator implements IntIterator
{
/**
* Index of element to be returned by subsequent call to next.
*/
private int currentIndex;
public boolean hasNext()
{
return this.currentIndex != CodePointAdapter.this.adapted.length();
}
public int next()
{
if (!this.hasNext())
{
throw new NoSuchElementException();
}
int next = CodePointAdapter.this.adapted.codePointAt(this.currentIndex);
this.currentIndex += Character.charCount(next);
return next;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy