Alternative class to allow for extensible Strings: How to work around java.lang.String being final? [closed]

大城市里の小女人 提交于 2021-02-20 05:35:59

问题


Recreating java.lang.String is not hard. See attached code.

I'm really writing this to show how easy it is. If anybody wants to figure out how to get the native isBigEndian() and add it in the solutions, that'd be great.

Other String methods would be great too.

Just put this code in your utilities package and you're good to go--unless you're running on a really old system that still uses littleEndian...

I'm building a new type of relational database that's 100 times faster than the fastest currently available relational databases (running on the same hardware) so extra waste from other solutions and the extra pointer load on memory as well as extra references/dereferences matter.

package com.paintedintel.util;

import java.nio.charset.StandardCharsets;

/**
 * 
 * @author David Urry
 * @date 2/8/2020
 * 
 * Strings is a light weight string implementation based on StringUTF16.
 * It's sole purpose is to create a system where strings can be extended
 * so that the type of string can be extended without the weight of carrying
 * extra object references.  
 * 
 * Strings extension is important for 2 reasons:
 * 1) The extra object reference slows the code down by a factor of 50% making 
 *    a 10X speed improvement only 5X.  As the object of looking at/comparing and
 *    otherwise managing strings is expensive.
 * 2) The code understanding benefits greatly from understanding the type of string
 *    you are working with (Name, Value, Field, InitValue, Comment...).  The constant
 *    evaluation of List<String> for example is greatly simplified when observing
 *    List<Field> instead.
 *    
 * This problem was also greatly simplified by working with Type, Domain, Datum,
 * StreamDomain, StreamCase and other objects as complex objects.
 */

public class Strings {
    final byte[] value;
    /** Cache the hash code for the string */
    private int hash; // Default to 0
 
    protected Strings(String value){
        if (value != null) {
            this.value = value.getBytes();
            this.hash = value.hashCode();
        } else {
            this.value = new byte[0];
            this.hash = 0;
        }
    }
    
    Strings(byte[] value){
        this.value = value;
        this.hash = Strings.hashCode(value);
    }
    
    @Override
    public String toString() {
        return new String(value, StandardCharsets.UTF_8);
    }
    
    public String str() {
        return toString();
    }
    
    public boolean equals(String str) {
        return (str == null)?((value == null || this.length() == 0)?true:false):str.hashCode() == value.hashCode();
    }
    
    public boolean eq(String str) {
        return equals(str);
    }
    
    byte[] getBytes() {
        return value;
    }
    
    int getHash() {
        return hash;
    }
    
    public int length() {
        return value.length >> 1;
    }
    
    /**
     * this is based on StringUTF16 
     * @param value
     * @return
     */
    synchronized public static int hashCode(byte[] value) {
        int h = 0;
        int length = value.length >> 1;
        for (int i = 0; i < length; i++) {
            h = 31 * h + getChar(value, i);
        }
        return h;
    }
    
    // intrinsic performs no bounds checks
    synchronized static char getChar(byte[] val, int index) {
        assert index >= 0 && index < length(val) : "Trusted caller missed bounds check";
        index <<= 1;
        return (char)(((val[index++] & 0xff) << HI_BYTE_SHIFT) |
                      ((val[index]   & 0xff) << LO_BYTE_SHIFT));
    }

    //private static native boolean isBigEndian();

//  private static boolean isBigEndian() {
//      //as of 2018 there are no major BigEndian systems left.
//      // This is because it's less processing to convert & work with
//      // Little-Endian.
//      return false;
//    }
    
    static final int HI_BYTE_SHIFT = 0;
    static final int LO_BYTE_SHIFT = 8;
//    static {
//        if (isBigEndian()) {
//            HI_BYTE_SHIFT = 8;
//            LO_BYTE_SHIFT = 0;
//        } else {
//            HI_BYTE_SHIFT = 0;
//            LO_BYTE_SHIFT = 8;
//        }
//    }
    
    synchronized public static int length(byte[] value) {
        return value.length >> 1;
    }
}

To extend Strings, do the following:

package com.paintedintel.util;

import com.paintedintel.util.Strings;

public class StrPassword extends Strings {

    public StrPassword(String value){
        super(value);
    }

    //Extend at will.

}

来源:https://stackoverflow.com/questions/66193450/alternative-class-to-allow-for-extensible-strings-how-to-work-around-java-lang

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!