All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cc.shacocloud.mirage.loader.jar.StringSequence Maven / Gradle / Ivy

There is a newer version: 2.1.0
Show newest version
package cc.shacocloud.mirage.loader.jar;

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;

/**
 * 由单个共享 {@link String} 支持的 {@link CharSequence}。与常规 {@link String} 不同,{@link #subSequence(int, int)} 操作不会复制底层字符数组。
 */
final class StringSequence implements CharSequence {
    
    private final String source;
    
    private final int start;
    
    private final int end;
    
    private int hash;
    
    StringSequence(@NotNull String source) {
        this(source, 0, source.length());
    }
    
    StringSequence(@NotNull String source, int start, int end) {
        if (start < 0) {
            throw new StringIndexOutOfBoundsException(start);
        }
        if (end > source.length()) {
            throw new StringIndexOutOfBoundsException(end);
        }
        this.source = source;
        this.start = start;
        this.end = end;
    }
    
    @NotNull StringSequence subSequence(int start) {
        return subSequence(start, length());
    }
    
    @Override
    public StringSequence subSequence(int start, int end) {
        int subSequenceStart = this.start + start;
        int subSequenceEnd = this.start + end;
        if (subSequenceStart > this.end) {
            throw new StringIndexOutOfBoundsException(start);
        }
        if (subSequenceEnd > this.end) {
            throw new StringIndexOutOfBoundsException(end);
        }
        if (start == 0 && subSequenceEnd == this.end) {
            return this;
        }
        return new StringSequence(this.source, subSequenceStart, subSequenceEnd);
    }
    
    /**
     * 如果序列为空,则返回 {@code true}
     */
    public boolean isEmpty() {
        return length() == 0;
    }
    
    @Override
    public int length() {
        return this.end - this.start;
    }
    
    @Override
    public char charAt(int index) {
        return this.source.charAt(this.start + index);
    }
    
    int indexOf(char ch) {
        return this.source.indexOf(ch, this.start) - this.start;
    }
    
    int indexOf(String str) {
        return this.source.indexOf(str, this.start) - this.start;
    }
    
    int indexOf(String str, int fromIndex) {
        return this.source.indexOf(str, this.start + fromIndex) - this.start;
    }
    
    boolean startsWith(String prefix) {
        return startsWith(prefix, 0);
    }
    
    boolean startsWith(@NotNull String prefix, int offset) {
        int prefixLength = prefix.length();
        int length = length();
        if (length - prefixLength - offset < 0) {
            return false;
        }
        return this.source.startsWith(prefix, this.start + offset);
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof CharSequence)) {
            return false;
        }
        CharSequence other = (CharSequence) obj;
        int n = length();
        if (n != other.length()) {
            return false;
        }
        int i = 0;
        while (n-- != 0) {
            if (charAt(i) != other.charAt(i)) {
                return false;
            }
            i++;
        }
        return true;
    }
    
    @Override
    public int hashCode() {
        int hash = this.hash;
        if (hash == 0 && length() > 0) {
            for (int i = this.start; i < this.end; i++) {
                hash = 31 * hash + this.source.charAt(i);
            }
            this.hash = hash;
        }
        return hash;
    }
    
    @Contract(pure = true)
    @Override
    public @NotNull String toString() {
        return this.source.substring(this.start, this.end);
    }
    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy