1452 lines
36 KiB
Python
1452 lines
36 KiB
Python
"""
|
|
Java lang standard library APIs implemented in Python.
|
|
java.lang package - String, Integer, Math, Thread, System, Object, etc.
|
|
"""
|
|
|
|
from .._core import Stub, AndroidOnlyError
|
|
import re as _re
|
|
import math as _py_math
|
|
import sys as _sys
|
|
import os as _os
|
|
import time as _time
|
|
import threading as _threading
|
|
import inspect as _inspect
|
|
import math
|
|
import random
|
|
import time
|
|
from datetime import datetime as _datetime
|
|
|
|
__all__ = [
|
|
"Object", "Throwable", "Exception", "RuntimeException", "Error",
|
|
"String", "Integer", "Long", "Short", "Byte", "Float", "Double",
|
|
"Boolean", "Character", "Math", "StrictMath", "System",
|
|
"Thread", "ThreadLocal", "StringBuilder", "StringBuffer",
|
|
"Class", "Void", "VoidType",
|
|
"Stub", "Comparable", "CharSequence", "Iterable", "Appendable",
|
|
"Readable", "AutoCloseable", "Cloneable", "Runnable",
|
|
"StackTraceElement", "Number", "SuppressWarnings", "Deprecated",
|
|
"Override", "FunctionalInterface",
|
|
]
|
|
|
|
|
|
# ============================================================
|
|
# Interfaces
|
|
# ============================================================
|
|
|
|
class Comparable(Stub):
|
|
def compareTo(self, other):
|
|
raise NotImplementedError
|
|
|
|
class Iterable(Stub):
|
|
def iterator(self):
|
|
raise NotImplementedError
|
|
|
|
class AutoCloseable(Stub):
|
|
def close(self):
|
|
raise NotImplementedError
|
|
|
|
class Cloneable(Stub):
|
|
def clone(self):
|
|
return self.__class__()
|
|
|
|
class CharSequence(Stub):
|
|
def length(self):
|
|
raise NotImplementedError
|
|
def charAt(self, index):
|
|
raise NotImplementedError
|
|
def subSequence(self, start, end):
|
|
raise NotImplementedError
|
|
def toString(self):
|
|
raise NotImplementedError
|
|
|
|
class Appendable(Stub):
|
|
def append(self, c):
|
|
raise NotImplementedError
|
|
|
|
class Readable(Stub):
|
|
def read(self, cb):
|
|
raise NotImplementedError
|
|
|
|
class Runnable(Stub):
|
|
def run(self):
|
|
pass
|
|
|
|
|
|
# ============================================================
|
|
# Throwable hierarchy
|
|
# ============================================================
|
|
|
|
class Throwable(Exception, Stub):
|
|
def __init__(self, message=None, cause=None):
|
|
super().__init__(message or "")
|
|
self._detail_message = str(message) if message else None
|
|
self._cause = cause
|
|
self._stack_trace = []
|
|
self._suppressed = []
|
|
self._fill_in_stack()
|
|
|
|
def _fill_in_stack(self):
|
|
import traceback
|
|
stack = traceback.extract_stack()
|
|
self._stack_trace = [
|
|
StackTraceElement(
|
|
frame.filename, frame.name, frame.filename, frame.lineno, False
|
|
)
|
|
for frame in stack[:-1]
|
|
]
|
|
|
|
def getMessage(self):
|
|
return self._detail_message
|
|
|
|
def getLocalizedMessage(self):
|
|
return self._detail_message
|
|
|
|
def getCause(self):
|
|
return self._cause
|
|
|
|
def initCause(self, cause):
|
|
self._cause = cause
|
|
return self
|
|
|
|
def toString(self):
|
|
msg = self._detail_message or ""
|
|
return f"{self.__class__.__name__}: {msg}" if msg else self.__class__.__name__
|
|
|
|
def printStackTrace(self, file=None):
|
|
import traceback
|
|
if file is None:
|
|
file = _sys.stderr
|
|
traceback.print_exc(file=file)
|
|
|
|
def fillInStackTrace(self):
|
|
self._fill_in_stack()
|
|
return self
|
|
|
|
def getStackTrace(self):
|
|
return self._stack_trace
|
|
|
|
def setStackTrace(self, stack_trace):
|
|
self._stack_trace = stack_trace
|
|
|
|
def addSuppressed(self, exception):
|
|
self._suppressed.append(exception)
|
|
|
|
def getSuppressed(self):
|
|
return self._suppressed
|
|
|
|
def __str__(self):
|
|
return self.toString()
|
|
|
|
|
|
class Exception(Throwable):
|
|
pass
|
|
|
|
class RuntimeException(Exception):
|
|
pass
|
|
|
|
class Error(Throwable):
|
|
pass
|
|
|
|
|
|
# ============================================================
|
|
# StackTraceElement
|
|
# ============================================================
|
|
|
|
class StackTraceElement(Stub):
|
|
def __init__(self, declaring_class, method_name, file_name, line_number, native_method):
|
|
super().__init__()
|
|
self._class = declaring_class
|
|
self._method = method_name
|
|
self._file = file_name
|
|
self._line = line_number
|
|
self._native = native_method
|
|
|
|
def getClassName(self):
|
|
return self._class
|
|
|
|
def getMethodName(self):
|
|
return self._method
|
|
|
|
def getFileName(self):
|
|
return self._file
|
|
|
|
def getLineNumber(self):
|
|
return self._line
|
|
|
|
def isNativeMethod(self):
|
|
return self._native
|
|
|
|
def toString(self):
|
|
return f"{self._class}.{self._method}({self._file}:{self._line})"
|
|
|
|
|
|
# ============================================================
|
|
# Object
|
|
# ============================================================
|
|
|
|
class Object(Stub):
|
|
def __init__(self):
|
|
super().__init__()
|
|
|
|
def getClass(self):
|
|
return self.__class__
|
|
|
|
def hashCode(self):
|
|
return hash(self) & 0x7FFFFFFF
|
|
|
|
def equals(self, other):
|
|
return self is other
|
|
|
|
def toString(self):
|
|
return f"{self.__class__.__name__}@{hex(id(self))}"
|
|
|
|
def notify(self):
|
|
pass
|
|
|
|
def notifyAll(self):
|
|
pass
|
|
|
|
def wait(self, timeout=None):
|
|
pass
|
|
|
|
def clone(self):
|
|
return self.__class__()
|
|
|
|
def finalize(self):
|
|
pass
|
|
|
|
|
|
# ============================================================
|
|
# String
|
|
# ============================================================
|
|
|
|
class String(CharSequence):
|
|
def __init__(self, value=None):
|
|
super().__init__()
|
|
if value is None:
|
|
self._str = ""
|
|
elif isinstance(value, bytes):
|
|
self._str = value.decode("utf-8", errors="replace")
|
|
else:
|
|
self._str = str(value)
|
|
|
|
def charAt(self, index):
|
|
return self._str[index]
|
|
|
|
def codePointAt(self, index):
|
|
return ord(self._str[index])
|
|
|
|
def codePointBefore(self, index):
|
|
return ord(self._str[index - 1]) if index > 0 else -1
|
|
|
|
def codePointCount(self, beginIndex, endIndex):
|
|
return endIndex - beginIndex
|
|
|
|
def compareTo(self, other):
|
|
if isinstance(other, String):
|
|
return (self._str > other._str) - (self._str < other._str)
|
|
return -1
|
|
|
|
def compareToIgnoreCase(self, other):
|
|
if isinstance(other, String):
|
|
return (self._str.lower() > other._str.lower()) - (self._str.lower() < other._str.lower())
|
|
return -1
|
|
|
|
def concat(self, s):
|
|
return String(self._str + str(s))
|
|
|
|
def contains(self, s):
|
|
return str(s) in self._str
|
|
|
|
def contentEquals(self, cs):
|
|
return self._str == str(cs)
|
|
|
|
def endsWith(self, suffix):
|
|
return self._str.endswith(suffix)
|
|
|
|
def equals(self, other):
|
|
if isinstance(other, String):
|
|
return self._str == other._str
|
|
return False
|
|
|
|
def equalsIgnoreCase(self, other):
|
|
if isinstance(other, String):
|
|
return self._str.lower() == other._str.lower()
|
|
return False
|
|
|
|
def getBytes(self, charset="UTF-8"):
|
|
return self._str.encode(charset, errors="replace")
|
|
|
|
def hashCode(self):
|
|
h = 0
|
|
for c in self._str:
|
|
h = (31 * h + ord(c)) & 0xFFFFFFFF
|
|
return h if h < 0x80000000 else h - 0x100000000
|
|
return h & 0x7FFFFFFF
|
|
|
|
def indexOf(self, ch, fromIndex=0):
|
|
if isinstance(ch, int):
|
|
ch = chr(ch)
|
|
return self._str.index(str(ch), fromIndex) if str(ch) in self._str[fromIndex:] else -1
|
|
|
|
def intern(self):
|
|
return self
|
|
|
|
def isEmpty(self):
|
|
return len(self._str) == 0
|
|
|
|
def lastIndexOf(self, ch, fromIndex=None):
|
|
if isinstance(ch, int):
|
|
ch = chr(ch)
|
|
if fromIndex is None:
|
|
fromIndex = len(self._str) - 1
|
|
search_in = self._str[:fromIndex + 1]
|
|
return search_in.rfind(str(ch)) if str(ch) in search_in else -1
|
|
|
|
def length(self):
|
|
return len(self._str)
|
|
|
|
def matches(self, regex):
|
|
return bool(_re.fullmatch(regex, self._str))
|
|
|
|
def offsetByCodePoints(self, index, codePointOffset):
|
|
return index + codePointOffset
|
|
|
|
def regionMatches(self, ignoreCase, toffset, other, ooffset, length):
|
|
if ignoreCase:
|
|
return self._str[toffset:toffset+length].lower() == other._str[ooffset:ooffset+length].lower()
|
|
return self._str[toffset:toffset+length] == other._str[ooffset:ooffset+length]
|
|
|
|
def replace(self, oldChar, newChar):
|
|
if isinstance(oldChar, int):
|
|
oldChar = chr(oldChar)
|
|
if isinstance(newChar, int):
|
|
newChar = chr(newChar)
|
|
return String(self._str.replace(oldChar, newChar))
|
|
|
|
def replaceAll(self, regex, replacement):
|
|
return String(_re.sub(regex, replacement, self._str))
|
|
|
|
def replaceFirst(self, regex, replacement):
|
|
return String(_re.sub(regex, replacement, self._str, count=1))
|
|
|
|
def split(self, regex, limit=0):
|
|
if limit <= 0:
|
|
parts = _re.split(regex, self._str)
|
|
if limit == 0:
|
|
while parts and parts[-1] == "":
|
|
parts.pop()
|
|
else:
|
|
parts = _re.split(regex, self._str, maxsplit=limit - 1)
|
|
while len(parts) < limit:
|
|
parts.append("")
|
|
return [String(p) for p in parts]
|
|
|
|
def startsWith(self, prefix):
|
|
return self._str.startswith(prefix)
|
|
|
|
def substring(self, beginIndex, endIndex=None):
|
|
if endIndex is None:
|
|
return String(self._str[beginIndex:])
|
|
return String(self._str[beginIndex:endIndex])
|
|
|
|
def toCharArray(self):
|
|
return list(self._str)
|
|
|
|
def toLowerCase(self):
|
|
return String(self._str.lower())
|
|
|
|
def toUpperCase(self):
|
|
return String(self._str.upper())
|
|
|
|
def trim(self):
|
|
return String(self._str.strip())
|
|
|
|
@staticmethod
|
|
def valueOf(obj):
|
|
return String(str(obj))
|
|
|
|
@staticmethod
|
|
def copyValueOf(data, offset=0, count=None):
|
|
if count is None:
|
|
return String("".join(data))
|
|
return String("".join(data[offset:offset+count]))
|
|
|
|
@staticmethod
|
|
def format(fmt, *args):
|
|
return String(str(fmt) % args if args else str(fmt))
|
|
|
|
@staticmethod
|
|
def join(delimiter, *elements):
|
|
if hasattr(elements[0], '__iter__') and not isinstance(elements[0], (str, bytes)):
|
|
elements = elements[0]
|
|
return String(str(delimiter).join(str(s) for s in elements))
|
|
|
|
def toString(self):
|
|
return self._str
|
|
|
|
def __str__(self):
|
|
return self._str
|
|
|
|
def __repr__(self):
|
|
return f"String({self._str!r})"
|
|
|
|
def __len__(self):
|
|
return len(self._str)
|
|
|
|
def __getitem__(self, idx):
|
|
return self._str[idx]
|
|
|
|
def __add__(self, other):
|
|
return String(self._str + str(other))
|
|
|
|
def __eq__(self, other):
|
|
if isinstance(other, String):
|
|
return self._str == other._str
|
|
return NotImplemented
|
|
|
|
|
|
# ============================================================
|
|
# Number
|
|
# ============================================================
|
|
|
|
class Number(Stub):
|
|
def intValue(self):
|
|
raise NotImplementedError
|
|
def longValue(self):
|
|
raise NotImplementedError
|
|
def floatValue(self):
|
|
raise NotImplementedError
|
|
def doubleValue(self):
|
|
raise NotImplementedError
|
|
def byteValue(self):
|
|
return self.intValue() & 0xFF
|
|
def shortValue(self):
|
|
return self.intValue() & 0xFFFF
|
|
|
|
|
|
# ============================================================
|
|
# Integer
|
|
# ============================================================
|
|
|
|
class Integer(Number, Comparable):
|
|
MAX_VALUE = 2147483647
|
|
MIN_VALUE = -2147483648
|
|
SIZE = 32
|
|
BYTES = 4
|
|
TYPE = int
|
|
|
|
def __init__(self, value=0):
|
|
super().__init__()
|
|
if isinstance(value, str):
|
|
self._value = Integer.parseInt(value)
|
|
else:
|
|
self._value = int(value)
|
|
|
|
@staticmethod
|
|
def parseInt(s, radix=10):
|
|
if isinstance(s, String):
|
|
s = str(s)
|
|
if radix == 10:
|
|
return int(str(s))
|
|
return int(str(s), radix)
|
|
|
|
@staticmethod
|
|
def toString(i, radix=10):
|
|
if radix == 10:
|
|
return String(str(i))
|
|
if radix == 2:
|
|
return String(bin(i)[2:])
|
|
if radix == 8:
|
|
return String(oct(i)[2:])
|
|
if radix == 16:
|
|
return String(hex(i)[2:])
|
|
return String(str(i))
|
|
|
|
@staticmethod
|
|
def toBinaryString(i):
|
|
if i >= 0:
|
|
return String(bin(i)[2:])
|
|
return String(bin(i & 0xFFFFFFFF)[2:])
|
|
|
|
@staticmethod
|
|
def toHexString(i):
|
|
if i >= 0:
|
|
return String(hex(i)[2:])
|
|
return String(hex(i & 0xFFFFFFFF)[2:])
|
|
|
|
@staticmethod
|
|
def toOctalString(i):
|
|
if i >= 0:
|
|
return String(oct(i)[2:])
|
|
return String(oct(i & 0xFFFFFFFF)[2:])
|
|
|
|
@staticmethod
|
|
def valueOf(i, radix=10):
|
|
if isinstance(i, str):
|
|
return Integer(Integer.parseInt(i, radix))
|
|
return Integer(i)
|
|
|
|
def intValue(self):
|
|
return self._value
|
|
|
|
def compareTo(self, other):
|
|
if isinstance(other, Integer):
|
|
return (self._value > other._value) - (self._value < other._value)
|
|
return -1
|
|
|
|
def equals(self, other):
|
|
if isinstance(other, Integer):
|
|
return self._value == other._value
|
|
return False
|
|
|
|
def byteValue(self):
|
|
return self._value & 0xFF
|
|
|
|
def shortValue(self):
|
|
return self._value & 0xFFFF
|
|
|
|
def longValue(self):
|
|
return self._value
|
|
|
|
def floatValue(self):
|
|
return float(self._value)
|
|
|
|
def doubleValue(self):
|
|
return float(self._value)
|
|
|
|
@staticmethod
|
|
def bitCount(i):
|
|
return bin(i & 0xFFFFFFFF).count("1")
|
|
|
|
@staticmethod
|
|
def highestOneBit(i):
|
|
if i == 0:
|
|
return 0
|
|
return 1 << (i.bit_length() - 1)
|
|
|
|
@staticmethod
|
|
def lowestOneBit(i):
|
|
return i & -i
|
|
|
|
@staticmethod
|
|
def numberOfLeadingZeros(i):
|
|
if i == 0:
|
|
return 32
|
|
return 32 - i.bit_length()
|
|
|
|
@staticmethod
|
|
def numberOfTrailingZeros(i):
|
|
if i == 0:
|
|
return 32
|
|
return (i & -i).bit_length() - 1
|
|
|
|
@staticmethod
|
|
def reverse(i):
|
|
v = i & 0xFFFFFFFF
|
|
result = 0
|
|
for _ in range(32):
|
|
result = (result << 1) | (v & 1)
|
|
v >>= 1
|
|
return result
|
|
|
|
@staticmethod
|
|
def reverseBytes(i):
|
|
v = i & 0xFFFFFFFF
|
|
return ((v >> 24) & 0xFF) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | ((v << 24) & 0xFF000000)
|
|
|
|
@staticmethod
|
|
def rotateLeft(i, distance):
|
|
v = i & 0xFFFFFFFF
|
|
d = distance & 31
|
|
return ((v << d) | (v >> (32 - d))) & 0xFFFFFFFF
|
|
|
|
@staticmethod
|
|
def rotateRight(i, distance):
|
|
v = i & 0xFFFFFFFF
|
|
d = distance & 31
|
|
return ((v >> d) | (v << (32 - d))) & 0xFFFFFFFF
|
|
|
|
@staticmethod
|
|
def signum(i):
|
|
if i > 0:
|
|
return 1
|
|
if i < 0:
|
|
return -1
|
|
return 0
|
|
|
|
@staticmethod
|
|
def decode(nm):
|
|
if nm.startswith("0x") or nm.startswith("0X"):
|
|
return Integer(int(nm, 16))
|
|
if nm.startswith("0") and len(nm) > 1:
|
|
return Integer(int(nm, 8))
|
|
if nm.startswith("#"):
|
|
return Integer(int(nm[1:], 16))
|
|
return Integer(int(nm))
|
|
|
|
@staticmethod
|
|
def getInteger(nm, val=None):
|
|
env_val = _os.environ.get(nm)
|
|
if env_val is not None:
|
|
return Integer(int(env_val))
|
|
return Integer(val) if val is not None else None
|
|
|
|
def toString(self):
|
|
return String(str(self._value))
|
|
|
|
def __str__(self):
|
|
return str(self._value)
|
|
|
|
def __int__(self):
|
|
return self._value
|
|
|
|
|
|
# ============================================================
|
|
# Long
|
|
# ============================================================
|
|
|
|
class Long(Number, Comparable):
|
|
MAX_VALUE = 9223372036854775807
|
|
MIN_VALUE = -9223372036854775808
|
|
SIZE = 64
|
|
BYTES = 8
|
|
TYPE = int
|
|
|
|
def __init__(self, value=0):
|
|
super().__init__()
|
|
if isinstance(value, str):
|
|
self._value = Long.parseLong(value)
|
|
else:
|
|
self._value = int(value)
|
|
|
|
@staticmethod
|
|
def parseLong(s, radix=10):
|
|
if isinstance(s, String):
|
|
s = str(s)
|
|
if radix == 10:
|
|
return int(str(s))
|
|
return int(str(s), radix)
|
|
|
|
@staticmethod
|
|
def toString(i, radix=10):
|
|
if radix == 10:
|
|
return String(str(i))
|
|
return String(str(i))
|
|
|
|
@staticmethod
|
|
def toBinaryString(i):
|
|
if i >= 0:
|
|
return String(bin(i)[2:])
|
|
return String(bin(i & 0xFFFFFFFFFFFFFFFF)[2:])
|
|
|
|
@staticmethod
|
|
def toHexString(i):
|
|
if i >= 0:
|
|
return String(hex(i)[2:])
|
|
return String(hex(i & 0xFFFFFFFFFFFFFFFF)[2:])
|
|
|
|
@staticmethod
|
|
def toOctalString(i):
|
|
if i >= 0:
|
|
return String(oct(i)[2:])
|
|
return String(oct(i & 0xFFFFFFFFFFFFFFFF)[2:])
|
|
|
|
@staticmethod
|
|
def valueOf(i, radix=10):
|
|
if isinstance(i, str):
|
|
return Long(Long.parseLong(i, radix))
|
|
return Long(i)
|
|
|
|
def longValue(self):
|
|
return self._value
|
|
|
|
def intValue(self):
|
|
return int(self._value)
|
|
|
|
def floatValue(self):
|
|
return float(self._value)
|
|
|
|
def doubleValue(self):
|
|
return float(self._value)
|
|
|
|
def compareTo(self, other):
|
|
if isinstance(other, Long):
|
|
return (self._value > other._value) - (self._value < other._value)
|
|
return -1
|
|
|
|
def equals(self, other):
|
|
if isinstance(other, Long):
|
|
return self._value == other._value
|
|
return False
|
|
|
|
def toString(self):
|
|
return String(str(self._value))
|
|
|
|
def __str__(self):
|
|
return str(self._value)
|
|
|
|
|
|
# ============================================================
|
|
# Short, Byte
|
|
# ============================================================
|
|
|
|
class Short(Number, Comparable):
|
|
MAX_VALUE = 32767
|
|
MIN_VALUE = -32768
|
|
SIZE = 16
|
|
BYTES = 2
|
|
TYPE = int
|
|
|
|
def __init__(self, value=0):
|
|
super().__init__()
|
|
if isinstance(value, str):
|
|
self._value = Short.parseShort(value)
|
|
else:
|
|
self._value = int(value) & 0xFFFF
|
|
|
|
@staticmethod
|
|
def parseShort(s, radix=10):
|
|
return int(str(s), radix)
|
|
|
|
@staticmethod
|
|
def valueOf(i, radix=10):
|
|
if isinstance(i, str):
|
|
return Short(Short.parseShort(i, radix))
|
|
return Short(i)
|
|
|
|
def shortValue(self):
|
|
return self._value
|
|
|
|
def intValue(self):
|
|
return self._value
|
|
|
|
def longValue(self):
|
|
return self._value
|
|
|
|
def floatValue(self):
|
|
return float(self._value)
|
|
|
|
def doubleValue(self):
|
|
return float(self._value)
|
|
|
|
def compareTo(self, other):
|
|
if isinstance(other, Short):
|
|
return (self._value > other._value) - (self._value < other._value)
|
|
return -1
|
|
|
|
def equals(self, other):
|
|
if isinstance(other, Short):
|
|
return self._value == other._value
|
|
return False
|
|
|
|
def toString(self):
|
|
return String(str(self._value))
|
|
|
|
|
|
class Byte(Number, Comparable):
|
|
MAX_VALUE = 127
|
|
MIN_VALUE = -128
|
|
SIZE = 8
|
|
BYTES = 1
|
|
TYPE = int
|
|
|
|
def __init__(self, value=0):
|
|
super().__init__()
|
|
if isinstance(value, str):
|
|
self._value = Byte.parseByte(value)
|
|
else:
|
|
self._value = int(value) & 0xFF
|
|
if self._value > 127:
|
|
self._value -= 256
|
|
|
|
@staticmethod
|
|
def parseByte(s, radix=10):
|
|
return int(str(s), radix)
|
|
|
|
@staticmethod
|
|
def valueOf(i, radix=10):
|
|
if isinstance(i, str):
|
|
return Byte(Byte.parseByte(i, radix))
|
|
return Byte(i)
|
|
|
|
def byteValue(self):
|
|
return self._value
|
|
|
|
def intValue(self):
|
|
return self._value
|
|
|
|
def longValue(self):
|
|
return self._value
|
|
|
|
def compareTo(self, other):
|
|
if isinstance(other, Byte):
|
|
return (self._value > other._value) - (self._value < other._value)
|
|
return -1
|
|
|
|
def equals(self, other):
|
|
if isinstance(other, Byte):
|
|
return self._value == other._value
|
|
return False
|
|
|
|
def toString(self):
|
|
return String(str(self._value))
|
|
|
|
|
|
# ============================================================
|
|
# Float
|
|
# ============================================================
|
|
|
|
class Float(Number, Comparable):
|
|
MAX_VALUE = 3.4028235e38
|
|
MIN_VALUE = 1.4e-45
|
|
MIN_NORMAL = 1.17549435e-38
|
|
MAX_EXPONENT = 127
|
|
MIN_EXPONENT = -126
|
|
SIZE = 32
|
|
BYTES = 4
|
|
TYPE = float
|
|
NaN = float("nan")
|
|
POSITIVE_INFINITY = float("inf")
|
|
NEGATIVE_INFINITY = float("-inf")
|
|
|
|
def __init__(self, value=0.0):
|
|
super().__init__()
|
|
if isinstance(value, str):
|
|
self._value = Float.parseFloat(value)
|
|
else:
|
|
self._value = float(value)
|
|
|
|
@staticmethod
|
|
def parseFloat(s):
|
|
if isinstance(s, String):
|
|
s = str(s)
|
|
s = str(s).strip()
|
|
if s == "NaN":
|
|
return float("nan")
|
|
if s == "Infinity" or s == "Inf":
|
|
return float("inf")
|
|
if s == "-Infinity" or s == "-Inf":
|
|
return float("-inf")
|
|
return float(s)
|
|
|
|
@staticmethod
|
|
def toString(f):
|
|
return String(str(f))
|
|
|
|
@staticmethod
|
|
def valueOf(f):
|
|
if isinstance(f, str):
|
|
return Float(Float.parseFloat(f))
|
|
return Float(f)
|
|
|
|
def floatValue(self):
|
|
return self._value
|
|
|
|
def intValue(self):
|
|
return int(self._value)
|
|
|
|
def longValue(self):
|
|
return int(self._value)
|
|
|
|
def doubleValue(self):
|
|
return float(self._value)
|
|
|
|
def compareTo(self, other):
|
|
if isinstance(other, Float):
|
|
a, b = self._value, other._value
|
|
if _py_math.isnan(a) and _py_math.isnan(b):
|
|
return 0
|
|
if _py_math.isnan(a):
|
|
return 1
|
|
if _py_math.isnan(b):
|
|
return -1
|
|
return (a > b) - (a < b)
|
|
return -1
|
|
|
|
def isNaN(self):
|
|
return _py_math.isnan(self._value)
|
|
|
|
def isInfinite(self):
|
|
return _py_math.isinf(self._value)
|
|
|
|
def equals(self, other):
|
|
if isinstance(other, Float):
|
|
if _py_math.isnan(self._value) and _py_math.isnan(other._value):
|
|
return True
|
|
return self._value == other._value
|
|
return False
|
|
|
|
def hashCode(self):
|
|
return _struct.pack(">f", self._value)
|
|
|
|
def toString(self):
|
|
return String(str(self._value))
|
|
|
|
def __str__(self):
|
|
return str(self._value)
|
|
|
|
import struct as _struct
|
|
|
|
|
|
# ============================================================
|
|
# Double
|
|
# ============================================================
|
|
|
|
class Double(Number, Comparable):
|
|
MAX_VALUE = 1.7976931348623157e308
|
|
MIN_VALUE = 4.9e-324
|
|
MIN_NORMAL = 2.2250738585072014e-308
|
|
MAX_EXPONENT = 1023
|
|
MIN_EXPONENT = -1022
|
|
SIZE = 64
|
|
BYTES = 8
|
|
TYPE = float
|
|
NaN = float("nan")
|
|
POSITIVE_INFINITY = float("inf")
|
|
NEGATIVE_INFINITY = float("-inf")
|
|
|
|
def __init__(self, value=0.0):
|
|
super().__init__()
|
|
if isinstance(value, str):
|
|
self._value = Double.parseDouble(value)
|
|
else:
|
|
self._value = float(value)
|
|
|
|
@staticmethod
|
|
def parseDouble(s):
|
|
if isinstance(s, String):
|
|
s = str(s)
|
|
s = str(s).strip()
|
|
if s == "NaN":
|
|
return float("nan")
|
|
if s == "Infinity" or s == "Inf":
|
|
return float("inf")
|
|
if s == "-Infinity" or s == "-Inf":
|
|
return float("-inf")
|
|
return float(s)
|
|
|
|
@staticmethod
|
|
def toString(d):
|
|
return String(str(d))
|
|
|
|
@staticmethod
|
|
def valueOf(d):
|
|
if isinstance(d, str):
|
|
return Double(Double.parseDouble(d))
|
|
return Double(d)
|
|
|
|
def doubleValue(self):
|
|
return self._value
|
|
|
|
def intValue(self):
|
|
return int(self._value)
|
|
|
|
def longValue(self):
|
|
return int(self._value)
|
|
|
|
def floatValue(self):
|
|
return float(self._value)
|
|
|
|
def compareTo(self, other):
|
|
if isinstance(other, Double):
|
|
a, b = self._value, other._value
|
|
if _py_math.isnan(a) and _py_math.isnan(b):
|
|
return 0
|
|
if _py_math.isnan(a):
|
|
return 1
|
|
if _py_math.isnan(b):
|
|
return -1
|
|
return (a > b) - (a < b)
|
|
return -1
|
|
|
|
def isNaN(self):
|
|
return _py_math.isnan(self._value)
|
|
|
|
def isInfinite(self):
|
|
return _py_math.isinf(self._value)
|
|
|
|
def equals(self, other):
|
|
if isinstance(other, Double):
|
|
if _py_math.isnan(self._value) and _py_math.isnan(other._value):
|
|
return True
|
|
return self._value == other._value
|
|
return False
|
|
|
|
def toString(self):
|
|
return String(str(self._value))
|
|
|
|
def __str__(self):
|
|
return str(self._value)
|
|
|
|
|
|
# ============================================================
|
|
# Boolean
|
|
# ============================================================
|
|
|
|
class Boolean(Stub):
|
|
TRUE = "true"
|
|
FALSE = "false"
|
|
TYPE = bool
|
|
|
|
def __init__(self, value=False):
|
|
super().__init__()
|
|
if isinstance(value, str):
|
|
self._value = Boolean.parseBoolean(value)
|
|
elif isinstance(value, bool):
|
|
self._value = value
|
|
else:
|
|
self._value = bool(value)
|
|
|
|
@staticmethod
|
|
def parseBoolean(s):
|
|
return str(s).lower() == "true"
|
|
|
|
@staticmethod
|
|
def toString(b):
|
|
return String(str(b).lower())
|
|
|
|
@staticmethod
|
|
def valueOf(b):
|
|
if isinstance(b, str):
|
|
return Boolean(Boolean.parseBoolean(b))
|
|
return Boolean(b)
|
|
|
|
def booleanValue(self):
|
|
return self._value
|
|
|
|
@staticmethod
|
|
def logicalAnd(a, b):
|
|
return a and b
|
|
|
|
@staticmethod
|
|
def logicalOr(a, b):
|
|
return a or b
|
|
|
|
@staticmethod
|
|
def logicalXor(a, b):
|
|
return a ^ b
|
|
|
|
def compareTo(self, other):
|
|
if isinstance(other, Boolean):
|
|
return (self._value > other._value) - (self._value < other._value)
|
|
return -1
|
|
|
|
def equals(self, other):
|
|
if isinstance(other, Boolean):
|
|
return self._value == other._value
|
|
return False
|
|
|
|
def toString(self):
|
|
return String("true" if self._value else "false")
|
|
|
|
def __str__(self):
|
|
return "true" if self._value else "false"
|
|
|
|
def __bool__(self):
|
|
return self._value
|
|
|
|
|
|
# ============================================================
|
|
# Character
|
|
# ============================================================
|
|
|
|
class Character(Stub):
|
|
MAX_VALUE = 65535
|
|
MIN_VALUE = 0
|
|
SIZE = 16
|
|
BYTES = 2
|
|
TYPE = str
|
|
|
|
def __init__(self, value=""):
|
|
super().__init__()
|
|
if isinstance(value, int):
|
|
self._value = chr(value)
|
|
else:
|
|
self._value = str(value)[0] if value else ""
|
|
|
|
def charValue(self):
|
|
return self._value
|
|
|
|
@staticmethod
|
|
def isDigit(ch):
|
|
return str(ch).isdigit()
|
|
|
|
@staticmethod
|
|
def isLetter(ch):
|
|
return str(ch).isalpha()
|
|
|
|
@staticmethod
|
|
def isLetterOrDigit(ch):
|
|
return str(ch).isalnum()
|
|
|
|
@staticmethod
|
|
def isLowerCase(ch):
|
|
return str(ch).islower()
|
|
|
|
@staticmethod
|
|
def isUpperCase(ch):
|
|
return str(ch).isupper()
|
|
|
|
@staticmethod
|
|
def isWhitespace(ch):
|
|
return str(ch).isspace()
|
|
|
|
@staticmethod
|
|
def isSpaceChar(ch):
|
|
return str(ch) in " \t\n\r\f\u000B"
|
|
|
|
@staticmethod
|
|
def isISOControl(ch):
|
|
c = ord(ch) if isinstance(ch, str) else ch
|
|
return c < 0x20 or c == 0x7F
|
|
|
|
@staticmethod
|
|
def isJavaIdentifierPart(ch):
|
|
c = str(ch)
|
|
return c.isalnum() or c == "_" or c == "$"
|
|
|
|
@staticmethod
|
|
def isJavaIdentifierStart(ch):
|
|
c = str(ch)
|
|
return c.isalpha() or c == "_" or c == "$"
|
|
|
|
@staticmethod
|
|
def isJavaLetter(ch):
|
|
return Character.isJavaIdentifierStart(ch)
|
|
|
|
@staticmethod
|
|
def isJavaLetterOrDigit(ch):
|
|
return Character.isJavaIdentifierPart(ch)
|
|
|
|
@staticmethod
|
|
def toLowerCase(ch):
|
|
return str(ch).lower()
|
|
|
|
@staticmethod
|
|
def toUpperCase(ch):
|
|
return str(ch).upper()
|
|
|
|
@staticmethod
|
|
def toTitleCase(ch):
|
|
return str(ch).upper()
|
|
|
|
@staticmethod
|
|
def getNumericValue(ch):
|
|
s = str(ch)
|
|
if s.isdigit():
|
|
return int(s)
|
|
if "a" <= s <= "z":
|
|
return ord(s) - ord("a") + 10
|
|
if "A" <= s <= "Z":
|
|
return ord(s) - ord("A") + 10
|
|
return -1
|
|
|
|
@staticmethod
|
|
def digit(ch, radix):
|
|
val = Character.getNumericValue(ch)
|
|
return val if val < radix else -1
|
|
|
|
@staticmethod
|
|
def forDigit(digit, radix):
|
|
if digit >= radix:
|
|
return "\0"
|
|
return str(digit) if digit < 10 else chr(ord("a") + digit - 10)
|
|
|
|
@staticmethod
|
|
def getType(ch):
|
|
return 0
|
|
|
|
@staticmethod
|
|
def getDirectionality(ch):
|
|
return 0
|
|
|
|
@staticmethod
|
|
def getName(ch):
|
|
return f"CHARACTER {ord(ch)}"
|
|
|
|
@staticmethod
|
|
def charCount(codePoint):
|
|
return 1 if codePoint < 0x10000 else 2
|
|
|
|
@staticmethod
|
|
def isBmpCodePoint(cp):
|
|
return cp <= 0xFFFF
|
|
|
|
@staticmethod
|
|
def isHighSurrogate(ch):
|
|
c = ord(ch) if isinstance(ch, str) else ch
|
|
return 0xD800 <= c <= 0xDBFF
|
|
|
|
@staticmethod
|
|
def isLowSurrogate(ch):
|
|
c = ord(ch) if isinstance(ch, str) else ch
|
|
return 0xDC00 <= c <= 0xDFFF
|
|
|
|
@staticmethod
|
|
def isSupplementaryCodePoint(cp):
|
|
return 0x10000
|
|
|
|
|
|
class Math:
|
|
"""java.lang.Math — 数学运算"""
|
|
E = 2.718281828459045
|
|
PI = 3.141592653589793
|
|
|
|
@staticmethod
|
|
def abs(a): return abs(a)
|
|
@staticmethod
|
|
def ceil(a): return int(math.ceil(a))
|
|
@staticmethod
|
|
def floor(a): return int(math.floor(a))
|
|
@staticmethod
|
|
def round(a): return round(a)
|
|
@staticmethod
|
|
def min(a, b): return a if a < b else b
|
|
@staticmethod
|
|
def max(a, b): return a if a > b else b
|
|
@staticmethod
|
|
def sqrt(a): return math.sqrt(a)
|
|
@staticmethod
|
|
def cbrt(a): return math.cbrt(a)
|
|
@staticmethod
|
|
def pow(a, b): return math.pow(a, b)
|
|
@staticmethod
|
|
def exp(a): return math.exp(a)
|
|
@staticmethod
|
|
def log(a): return math.log(a)
|
|
@staticmethod
|
|
def log10(a): return math.log10(a)
|
|
@staticmethod
|
|
def sin(a): return math.sin(a)
|
|
@staticmethod
|
|
def cos(a): return math.cos(a)
|
|
@staticmethod
|
|
def tan(a): return math.tan(a)
|
|
@staticmethod
|
|
def asin(a): return math.asin(a)
|
|
@staticmethod
|
|
def acos(a): return math.acos(a)
|
|
@staticmethod
|
|
def atan(a): return math.atan(a)
|
|
@staticmethod
|
|
def atan2(y, x): return math.atan2(y, x)
|
|
@staticmethod
|
|
def toDegrees(r): return math.degrees(r)
|
|
@staticmethod
|
|
def toRadians(d): return math.radians(d)
|
|
@staticmethod
|
|
def hypot(x, y): return math.hypot(x, y)
|
|
@staticmethod
|
|
def sinh(x): return math.sinh(x)
|
|
@staticmethod
|
|
def cosh(x): return math.cosh(x)
|
|
@staticmethod
|
|
def tanh(x): return math.tanh(x)
|
|
@staticmethod
|
|
def signum(x): return 0.0 if x == 0 else (1.0 if x > 0 else -1.0)
|
|
@staticmethod
|
|
def random(): return random.random()
|
|
@staticmethod
|
|
def addExact(x, y):
|
|
result = x + y
|
|
if (x > 0 and y > 0 and result < 0) or (x < 0 and y < 0 and result > 0):
|
|
raise ArithmeticError("integer overflow")
|
|
return result
|
|
@staticmethod
|
|
def copySign(m, s): return abs(m) * (1 if s >= 0 else -1)
|
|
@staticmethod
|
|
def floorDiv(x, y): return x // y if (x ^ y) >= 0 else -(abs(x) // abs(y))
|
|
@staticmethod
|
|
def floorMod(x, y): return x - Math.floorDiv(x, y) * y
|
|
|
|
|
|
class StrictMath(Math):
|
|
"""java.lang.StrictMath"""
|
|
pass
|
|
|
|
|
|
class System:
|
|
"""java.lang.System"""
|
|
@staticmethod
|
|
def currentTimeMillis(): return int(time.time() * 1000)
|
|
@staticmethod
|
|
def nanoTime(): return time.perf_counter_ns()
|
|
@staticmethod
|
|
def arraycopy(src, srcPos, dest, destPos, length):
|
|
if isinstance(src, (list, bytearray)):
|
|
dest[destPos:destPos+length] = src[srcPos:srcPos+length]
|
|
else:
|
|
raise TypeError("Unsupported type for arraycopy")
|
|
@staticmethod
|
|
def identityHashCode(obj): return id(obj) & 0x7FFFFFFF
|
|
@staticmethod
|
|
def gc(): pass
|
|
@staticmethod
|
|
def exit(status): raise SystemExit(status)
|
|
@staticmethod
|
|
def getProperty(key, default=None):
|
|
import os
|
|
return os.environ.get(key, default)
|
|
@staticmethod
|
|
def setProperty(key, value):
|
|
import os
|
|
os.environ[key] = value
|
|
return value
|
|
@staticmethod
|
|
def lineSeparator(): return _os.linesep
|
|
in_ = _sys.stdin
|
|
out = _sys.stdout
|
|
err = _sys.stderr
|
|
|
|
|
|
class Thread(Runnable):
|
|
"""java.lang.Thread"""
|
|
MIN_PRIORITY = 1
|
|
NORM_PRIORITY = 5
|
|
MAX_PRIORITY = 10
|
|
|
|
def __init__(self, target=None, name=None):
|
|
super().__init__()
|
|
self._target = target
|
|
self._name = name or f"Thread-{id(self)}"
|
|
self._alive = False
|
|
self._daemon = False
|
|
self._interrupted = False
|
|
|
|
def start(self):
|
|
self._alive = True
|
|
if self._target:
|
|
_threading.Thread(target=self.run, daemon=self._daemon).start()
|
|
|
|
def run(self):
|
|
if self._target:
|
|
self._target()
|
|
|
|
def interrupt(self):
|
|
self._interrupted = True
|
|
|
|
def isInterrupted(self):
|
|
return self._interrupted
|
|
|
|
def isAlive(self):
|
|
return self._alive
|
|
|
|
def getName(self): return self._name
|
|
def setName(self, n): self._name = n
|
|
def setDaemon(self, d): self._daemon = d
|
|
def isDaemon(self): return self._daemon
|
|
|
|
@staticmethod
|
|
def currentThread():
|
|
return Thread(name="main")
|
|
@staticmethod
|
|
def sleep(millis):
|
|
import time
|
|
time.sleep(millis / 1000.0)
|
|
@staticmethod
|
|
def yield_():
|
|
import time
|
|
time.sleep(0)
|
|
|
|
|
|
class ThreadLocal(Stub):
|
|
"""java.lang.ThreadLocal"""
|
|
def __init__(self):
|
|
super().__init__()
|
|
self._data = {}
|
|
|
|
def get(self):
|
|
tid = _threading.get_ident()
|
|
return self._data.get(tid, None)
|
|
def set(self, value):
|
|
self._data[_threading.get_ident()] = value
|
|
def remove(self):
|
|
self._data.pop(_threading.get_ident(), None)
|
|
|
|
|
|
class StringBuilder(Stub):
|
|
"""java.lang.StringBuilder — 可变字符序列"""
|
|
def __init__(self, s=""):
|
|
super().__init__()
|
|
self._buf = list(str(s))
|
|
|
|
def append(self, obj):
|
|
if isinstance(obj, bool):
|
|
self._buf.append("true" if obj else "false")
|
|
else:
|
|
self._buf.append(str(obj))
|
|
return self
|
|
|
|
def insert(self, offset, obj):
|
|
self._buf[offset:offset] = list(str(obj))
|
|
return self
|
|
|
|
def delete(self, start, end):
|
|
del self._buf[start:end]
|
|
return self
|
|
|
|
def deleteCharAt(self, index):
|
|
del self._buf[index]
|
|
return self
|
|
|
|
def replace(self, start, end, s):
|
|
self._buf[start:end] = list(s)
|
|
return self
|
|
|
|
def reverse(self):
|
|
self._buf.reverse()
|
|
return self
|
|
|
|
def toString(self): return "".join(self._buf)
|
|
def length(self): return len(self._buf)
|
|
def capacity(self): return len(self._buf) + 16
|
|
def charAt(self, i): return self._buf[i]
|
|
def setCharAt(self, i, c): self._buf[i] = c
|
|
def substring(self, s, e=None):
|
|
return "".join(self._buf[s:e])
|
|
def indexOf(self, s, f=0):
|
|
return self.toString().find(s, f)
|
|
def lastIndexOf(self, s, f=None):
|
|
return self.toString().rfind(s)
|
|
|
|
|
|
class StringBuffer(StringBuilder):
|
|
"""java.lang.StringBuffer — 线程安全的可变字符序列"""
|
|
pass
|
|
|
|
|
|
class Class(Stub):
|
|
"""java.lang.Class"""
|
|
def __init__(self, cls):
|
|
super().__init__()
|
|
self._cls = cls
|
|
def getName(self): return self._cls.__name__
|
|
def getSimpleName(self): return self._cls.__name__
|
|
def getCanonicalName(self): return self._cls.__name__
|
|
def isInterface(self): return isinstance(self._cls, type)
|
|
def isArray(self): return self._cls is list
|
|
def isPrimitive(self): return self._cls in (int, float, bool, str, bytes)
|
|
def getSuperclass(self): return Class(self._cls.__base__) if self._cls.__base__ else None
|
|
def cast(self, obj): return obj
|
|
|
|
|
|
class Void(Stub):
|
|
"""java.lang.Void"""
|
|
TYPE = None
|
|
|
|
|
|
class VoidType(Stub):
|
|
"""java.lang.Void (inner type)"""
|
|
pass
|
|
|
|
|
|
# 注解类
|
|
class SuppressWarnings(Stub):
|
|
pass
|
|
class Deprecated(Stub):
|
|
pass
|
|
class Override(Stub):
|
|
pass
|
|
class FunctionalInterface(Stub):
|
|
pass |