""" Java java.util standard library APIs implemented in Python. Android-pyApi: desktop Python translation of Android Java APIs. """ from .._core import Stub from .lang import RuntimeException import heapq as _heapq import bisect as _bisect import datetime as _datetime import uuid as _uuid import random as _py_random import math as _py_math import copy as _copy import re as _re import io as _io import threading as _threading import time as _time from typing import Any, Dict, List, Callable, Tuple, Iterable as _IterableType import typing as _typing from collections.abc import Iterable as _IterableABC __all__ = [ "ArrayList", "LinkedList", "HashMap", "LinkedHashMap", "TreeMap", "HashSet", "TreeSet", "LinkedHashSet", "Collections", "Arrays", "Date", "Calendar", "GregorianCalendar", "UUID", "StringTokenizer", "Optional", "Random", "Properties", "EnumSet", "EnumMap", "Iterator", "ListIterator", "Enumeration", "Objects", "Locale", "BitSet", "PriorityQueue", "Vector", "Stack", "ConcurrentModificationException", "NoSuchElementException", "EmptyStackException", "TooManyListenersException", "MissingResourceException", "IllegalFormatException", "DuplicateFormatFlagsException", "FormatFlagsConversionMismatchException", "FormatterClosedException", ] # ============================================================ # Exceptions # ============================================================ # Define exception classes in correct dependency order. # IllegalArgumentException comes before IllegalFormatException. IllegalArgumentException = type("IllegalArgumentException", (RuntimeException,), {}) ConcurrentModificationException = type( "ConcurrentModificationException", (RuntimeException,), {} ) NoSuchElementException = type("NoSuchElementException", (RuntimeException,), {}) EmptyStackException = type("EmptyStackException", (RuntimeException,), {}) TooManyListenersException = type("TooManyListenersException", (Exception,), {}) MissingResourceException = type("MissingResourceException", (RuntimeException,), {}) IllegalFormatException = type("IllegalFormatException", (IllegalArgumentException,), {}) DuplicateFormatFlagsException = type( "DuplicateFormatFlagsException", (IllegalFormatException,), {} ) FormatFlagsConversionMismatchException = type( "FormatFlagsConversionMismatchException", (IllegalFormatException,), {} ) # We need IllegalStateException for FormatterClosedException from .lang import RuntimeException as _RuntimeException IllegalStateException = type("IllegalStateException", (_RuntimeException,), {}) FormatterClosedException = type("FormatterClosedException", (IllegalStateException,), {}) UnsupportedOperationException = type("UnsupportedOperationException", (RuntimeException,), {}) # ============================================================ # Iterator / ListIterator / Enumeration # ============================================================ class Iterator(Stub): """java.util.Iterator""" def __init__(self, data): super().__init__() self._data = list(data) self._index = 0 self._mod_count = 0 def hasNext(self) -> bool: return self._index < len(self._data) def next(self): if not self.hasNext(): raise NoSuchElementException() val = self._data[self._index] self._index += 1 return val def remove(self): raise UnsupportedOperationException("remove") def forEachRemaining(self, action): while self.hasNext(): action(self.next()) class ListIterator(Iterator): """java.util.ListIterator""" def __init__(self, data): super().__init__(data) def hasPrevious(self) -> bool: return self._index > 0 def previous(self): if not self.hasPrevious(): raise NoSuchElementException() self._index -= 1 return self._data[self._index] def nextIndex(self) -> int: return self._index def previousIndex(self) -> int: return self._index - 1 def set(self, obj): self._data[self._index - 1] = obj def add(self, obj): self._data.insert(self._index, obj) self._index += 1 class Enumeration(Stub): """java.util.Enumeration""" def __init__(self, data): super().__init__() self._it = iter(data) def hasMoreElements(self) -> bool: try: self._next = next(self._it) return True except StopIteration: return False def nextElement(self): if hasattr(self, '_next'): val = self._next del self._next return val return next(self._it) def asIterator(self) -> Iterator: return Iterator(self._it) # ============================================================ # ArrayList # ============================================================ class ArrayList(Stub): """java.util.ArrayList — backed by Python list""" def __init__(self, initial_capacity: Any = None): super().__init__() if initial_capacity is None: self._data = [] elif isinstance(initial_capacity, int): self._data = [] elif isinstance(initial_capacity, _IterableABC): self._data = list(initial_capacity) else: self._data = [] def add(self, obj) -> bool: self._data.append(obj) return True def addAt(self, index: int, obj) -> None: self._data.insert(index, obj) def addAll(self, c) -> bool: if isinstance(c, ArrayList): self._data.extend(c._data) else: self._data.extend(c) return True def addAllAt(self, index: int, c) -> bool: if isinstance(c, ArrayList): self._data[index:index] = c._data else: self._data[index:index] = list(c) return True def clear(self) -> None: self._data.clear() def clone(self) -> 'ArrayList': return ArrayList(self._data) def contains(self, obj) -> bool: return obj in self._data def containsAll(self, c) -> bool: if isinstance(c, ArrayList): return all(x in self._data for x in c._data) return all(x in self._data for x in c) def ensureCapacity(self, min_capacity: int) -> None: pass # Python list handles resizing automatically def get(self, index: int): return self._data[index] def indexOf(self, obj) -> int: try: return self._data.index(obj) except ValueError: return -1 def isEmpty(self) -> bool: return len(self._data) == 0 def iterator(self) -> Iterator: return Iterator(self._data) def listIterator(self) -> ListIterator: return ListIterator(self._data) def lastIndexOf(self, obj) -> int: try: return len(self._data) - 1 - self._data[::-1].index(obj) except ValueError: return -1 def remove(self, obj) -> bool: if obj in self._data: self._data.remove(obj) return True return False def removeAt(self, index: int): return self._data.pop(index) def removeAll(self, c) -> bool: if isinstance(c, ArrayList): items = c._data else: items = list(c) old_len = len(self._data) self._data = [x for x in self._data if x not in items] return len(self._data) != old_len def retainAll(self, c) -> bool: if isinstance(c, ArrayList): items = set(c._data) else: items = set(c) old_len = len(self._data) self._data = [x for x in self._data if x in items] return len(self._data) != old_len def set(self, index: int, obj): old = self._data[index] self._data[index] = obj return old def size(self) -> int: return len(self._data) def sort(self, key=None, reverse: bool = False) -> None: self._data.sort(key=key, reverse=reverse) def subList(self, from_index: int, to_index: int) -> 'ArrayList': return ArrayList(self._data[from_index:to_index]) def toArray(self, a=None): if a is None: return list(self._data) if len(a) < len(self._data): return list(self._data) for i, v in enumerate(self._data): a[i] = v if len(self._data) < len(a): a[len(self._data)] = None return a def trimToSize(self) -> None: pass def forEach(self, action) -> None: for item in self._data: action(item) def removeIf(self, predicate) -> bool: old_len = len(self._data) self._data = [x for x in self._data if not predicate(x)] return len(self._data) != old_len def replaceAll(self, operator) -> None: self._data = [operator(x) for x in self._data] def equals(self, other) -> bool: if isinstance(other, ArrayList): return self._data == other._data return False def hashCode(self) -> int: h = 1 for v in self._data: h = (31 * h + hash(v)) & 0x7FFFFFFF return h def toString(self) -> str: items = ", ".join(str(x) for x in self._data) return f"[{items}]" def __len__(self): return len(self._data) def __getitem__(self, idx): return self._data[idx] def __setitem__(self, idx, val): self._data[idx] = val def __delitem__(self, idx): del self._data[idx] def __iter__(self): return iter(self._data) def __repr__(self): return self.toString() def __contains__(self, obj): return obj in self._data def __add__(self, other): if isinstance(other, ArrayList): result = ArrayList(self._data) result._data.extend(other._data) return result return NotImplemented def __eq__(self, other): return self.equals(other) # ============================================================ # LinkedList # ============================================================ class LinkedList(Stub): """java.util.LinkedList — backed by Python list""" def __init__(self, c=None): super().__init__() if c is None: self._data = [] elif isinstance(c, _IterableABC): self._data = list(c) else: self._data = [] def add(self, obj) -> bool: self._data.append(obj) return True def addFirst(self, obj) -> None: self._data.insert(0, obj) def addLast(self, obj) -> None: self._data.append(obj) def addAt(self, index: int, obj) -> None: self._data.insert(index, obj) def addAll(self, c) -> bool: if isinstance(c, LinkedList): self._data.extend(c._data) else: self._data.extend(c) return True def clear(self) -> None: self._data.clear() def clone(self) -> 'LinkedList': return LinkedList(self._data) def contains(self, obj) -> bool: return obj in self._data def descendingIterator(self) -> Iterator: return Iterator(reversed(self._data)) def element(self): if not self._data: raise NoSuchElementException() return self._data[0] def get(self, index: int): return self._data[index] def getFirst(self): if not self._data: raise NoSuchElementException() return self._data[0] def getLast(self): if not self._data: raise NoSuchElementException() return self._data[-1] def indexOf(self, obj) -> int: try: return self._data.index(obj) except ValueError: return -1 def isEmpty(self) -> bool: return len(self._data) == 0 def iterator(self) -> Iterator: return Iterator(self._data) def lastIndexOf(self, obj) -> int: try: return len(self._data) - 1 - self._data[::-1].index(obj) except ValueError: return -1 def listIterator(self, index: int = 0) -> ListIterator: li = ListIterator(self._data) li._index = index return li def offer(self, obj) -> bool: self._data.append(obj) return True def offerFirst(self, obj) -> bool: self._data.insert(0, obj) return True def offerLast(self, obj) -> bool: self._data.append(obj) return True def peek(self): return self._data[0] if self._data else None def peekFirst(self): return self._data[0] if self._data else None def peekLast(self): return self._data[-1] if self._data else None def poll(self): return self._data.pop(0) if self._data else None def pollFirst(self): return self._data.pop(0) if self._data else None def pollLast(self): return self._data.pop() if self._data else None def pop(self): if not self._data: raise NoSuchElementException() return self._data.pop() def push(self, obj) -> None: self._data.insert(0, obj) def remove(self, obj) -> bool: if obj in self._data: self._data.remove(obj) return True return False def removeAt(self, index: int): return self._data.pop(index) def removeFirst(self): if not self._data: raise NoSuchElementException() return self._data.pop(0) def removeFirstOccurrence(self, obj) -> bool: try: idx = self._data.index(obj) self._data.pop(idx) return True except ValueError: return False def removeLast(self): if not self._data: raise NoSuchElementException() return self._data.pop() def removeLastOccurrence(self, obj) -> bool: try: idx = len(self._data) - 1 - self._data[::-1].index(obj) self._data.pop(idx) return True except ValueError: return False def set(self, index: int, obj): old = self._data[index] self._data[index] = obj return old def size(self) -> int: return len(self._data) def toArray(self, a=None): if a is None: return list(self._data) if len(a) < len(self._data): return list(self._data) for i, v in enumerate(self._data): a[i] = v if len(self._data) < len(a): a[len(self._data)] = None return a def forEach(self, action) -> None: for item in self._data: action(item) def equals(self, other) -> bool: if isinstance(other, LinkedList): return self._data == other._data return False def hashCode(self) -> int: h = 1 for v in self._data: h = (31 * h + hash(v)) & 0x7FFFFFFF return h def toString(self) -> str: items = ", ".join(str(x) for x in self._data) return f"[{items}]" def __len__(self): return len(self._data) def __getitem__(self, idx): return self._data[idx] def __iter__(self): return iter(self._data) def __repr__(self): return self.toString() def __eq__(self, other): return self.equals(other) # ============================================================ # HashMap # ============================================================ class HashMap(Stub): """java.util.HashMap — backed by Python dict""" def __init__(self, initial_capacity: Any = None, load_factor: float = 0.75): super().__init__() self._data: Dict = {} if initial_capacity is not None and not isinstance(initial_capacity, (int, float)): if isinstance(initial_capacity, HashMap): self._data.update(initial_capacity._data) elif isinstance(initial_capacity, dict): self._data.update(initial_capacity) elif isinstance(initial_capacity, _IterableABC): for item in initial_capacity: if hasattr(item, 'getKey') and hasattr(item, 'getValue'): k, v = item.getKey(), item.getValue() elif isinstance(item, tuple) and len(item) >= 2: k, v = item[0], item[1] else: continue self._data[k] = v def clear(self) -> None: self._data.clear() def clone(self) -> 'HashMap': return HashMap(self._data) def compute(self, key, remapping_function): old = self._data.get(key) new_val = remapping_function(key, old) if new_val is not None: self._data[key] = new_val return new_val self._data.pop(key, None) return None def computeIfAbsent(self, key, mapping_function): if key not in self._data: new_val = mapping_function(key) if new_val is not None: self._data[key] = new_val return new_val return self._data.get(key) def computeIfPresent(self, key, remapping_function): if key in self._data: new_val = remapping_function(key, self._data[key]) if new_val is not None: self._data[key] = new_val return new_val self._data.pop(key, None) return None def containsKey(self, key) -> bool: return key in self._data def containsValue(self, value) -> bool: return value in self._data.values() def entrySet(self) -> set: return self._data.items() def forEach(self, action) -> None: for k, v in self._data.items(): action(k, v) def get(self, key): return self._data.get(key) def getOrDefault(self, key, default): return self._data.get(key, default) def isEmpty(self) -> bool: return len(self._data) == 0 def keySet(self) -> set: return set(self._data.keys()) def merge(self, key, value, remapping_function): old = self._data.get(key) if old is None: self._data[key] = value return value new_val = remapping_function(old, value) if new_val is not None: self._data[key] = new_val return new_val self._data.pop(key, None) return None def put(self, key, value): old = self._data.get(key) self._data[key] = value return old def putAll(self, m) -> None: if isinstance(m, HashMap): self._data.update(m._data) else: self._data.update(m) def putIfAbsent(self, key, value): if key not in self._data: self._data[key] = value return None return self._data[key] def remove(self, key, value=None) -> bool: if value is None: return self._data.pop(key, None) is not None or key in self._data if key in self._data and self._data[key] == value: del self._data[key] return True return False def replace(self, key, old_value=None, new_value=None): if old_value is None and new_value is None: return None if new_value is None: # replace(key, value) form if key in self._data: old = self._data[key] self._data[key] = old_value # old_value is actually new value here return old return None # replace(key, oldValue, newValue) form if key in self._data and self._data[key] == old_value: self._data[key] = new_value return True return False def replaceAll(self, function) -> None: for k in list(self._data.keys()): self._data[k] = function(k, self._data[k]) def size(self) -> int: return len(self._data) def values(self): return list(self._data.values()) def equals(self, other) -> bool: if isinstance(other, HashMap): return self._data == other._data return False def hashCode(self) -> int: h = 0 for k, v in self._data.items(): h = (h + (hash(k) ^ hash(v))) & 0x7FFFFFFF return h def toString(self) -> str: items = ", ".join(f"{k}={v}" for k, v in self._data.items()) return f"{{{items}}}" def __len__(self): return len(self._data) def __getitem__(self, key): return self._data[key] def __setitem__(self, key, value): self._data[key] = value def __delitem__(self, key): del self._data[key] def __iter__(self): return iter(self._data) def __contains__(self, key): return key in self._data def __repr__(self): return self.toString() def __eq__(self, other): return self.equals(other) # ============================================================ # LinkedHashMap # ============================================================ class LinkedHashMap(HashMap): """java.util.LinkedHashMap — backed by dict (preserves order in Python 3.7+)""" def __init__(self, initial_capacity: Any = None, load_factor: float = 0.75, access_order: bool = False): super().__init__(initial_capacity, load_factor) self._access_order = access_order def get(self, key): val = self._data.get(key) if val is not None and self._access_order: # Move to end (most recently accessed) by delete/reinsert del self._data[key] self._data[key] = val return val def getOrDefault(self, key, default): val = self._data.get(key, default) if key in self._data and self._access_order: del self._data[key] self._data[key] = val return val def put(self, key, value): old = self._data.get(key) if key in self._data: del self._data[key] self._data[key] = value return old def removeEldestEntry(self, eldest) -> bool: return False def eldest(self): if not self._data: return None key = next(iter(self._data)) return (key, self._data[key]) # ============================================================ # TreeMap # ============================================================ class TreeMap(Stub): """java.util.TreeMap — sorted map using Python's sorted()""" def __init__(self, comparator=None, m=None): super().__init__() self._data: Dict = {} self._comparator = comparator if m is not None: if isinstance(m, TreeMap): self._data.update(m._data) elif isinstance(m, dict): self._data.update(m) elif isinstance(m, _IterableABC): for item in m: if isinstance(item, tuple) and len(item) >= 2: self._data[item[0]] = item[1] def _sorted_keys(self): key_fn = self._comparator if self._comparator else None return sorted(self._data.keys(), key=key_fn) def _get_entry_by_key(self, key): if key in self._data: return (key, self._data[key]) return None def clear(self) -> None: self._data.clear() def clone(self) -> 'TreeMap': return TreeMap(self._comparator, self._data) def comparator(self): return self._comparator def containsKey(self, key) -> bool: return key in self._data def containsValue(self, value) -> bool: return value in self._data.values() def ceilingKey(self, key): keys = self._sorted_keys() for k in keys: if (self._comparator(k, key) >= 0 if self._comparator else k >= key): return k return None def ceilingEntry(self, key): k = self.ceilingKey(key) return (k, self._data[k]) if k is not None else None def floorKey(self, key): keys = self._sorted_keys() for k in reversed(keys): if (self._comparator(k, key) <= 0 if self._comparator else k <= key): return k return None def floorEntry(self, key): k = self.floorKey(key) return (k, self._data[k]) if k is not None else None def higherKey(self, key): keys = self._sorted_keys() for k in keys: if (self._comparator(k, key) > 0 if self._comparator else k > key): return k return None def higherEntry(self, key): k = self.higherKey(key) return (k, self._data[k]) if k is not None else None def lowerKey(self, key): keys = self._sorted_keys() for k in reversed(keys): if (self._comparator(k, key) < 0 if self._comparator else k < key): return k return None def lowerEntry(self, key): k = self.lowerKey(key) return (k, self._data[k]) if k is not None else None def firstKey(self): if not self._data: raise NoSuchElementException() return self._sorted_keys()[0] def firstEntry(self): k = self.firstKey() return (k, self._data[k]) def lastKey(self): if not self._data: raise NoSuchElementException() return self._sorted_keys()[-1] def lastEntry(self): k = self.lastKey() return (k, self._data[k]) def pollFirstEntry(self): if not self._data: return None k = self.firstKey() v = self._data.pop(k) return (k, v) def pollLastEntry(self): if not self._data: return None k = self.lastKey() v = self._data.pop(k) return (k, v) def entrySet(self): return [(k, self._data[k]) for k in self._sorted_keys()] def forEach(self, action) -> None: for k in self._sorted_keys(): action(k, self._data[k]) def get(self, key): return self._data.get(key) def getOrDefault(self, key, default): return self._data.get(key, default) def headMap(self, to_key, inclusive: bool = False) -> 'TreeMap': result = TreeMap(self._comparator) for k in self._sorted_keys(): cmp = self._comparator(k, to_key) if self._comparator else (k < to_key) if cmp or (inclusive and (self._comparator(k, to_key) == 0 if self._comparator else k == to_key)): result._data[k] = self._data[k] elif not inclusive and (self._comparator(k, to_key) < 0 if self._comparator else k < to_key): result._data[k] = self._data[k] else: break return result def tailMap(self, from_key, inclusive: bool = True) -> 'TreeMap': result = TreeMap(self._comparator) started = False for k in self._sorted_keys(): cmp = self._comparator(k, from_key) if self._comparator else (k >= from_key) if cmp or (inclusive and (self._comparator(k, from_key) == 0 if self._comparator else k == from_key)): started = True if started: result._data[k] = self._data[k] return result def subMap(self, from_key, to_key, from_inclusive: bool = True, to_inclusive: bool = False) -> 'TreeMap': result = TreeMap(self._comparator) for k in self._sorted_keys(): cmp_from = self._comparator(k, from_key) if self._comparator else (k >= from_key if from_inclusive else k > from_key) cmp_to = self._comparator(k, to_key) if self._comparator else (k <= to_key if to_inclusive else k < to_key) if cmp_from and cmp_to: result._data[k] = self._data[k] return result def isEmpty(self) -> bool: return len(self._data) == 0 def keySet(self): return self._sorted_keys() def put(self, key, value): old = self._data.get(key) self._data[key] = value return old def putAll(self, m) -> None: if isinstance(m, TreeMap): self._data.update(m._data) else: self._data.update(m) def putIfAbsent(self, key, value): if key not in self._data: self._data[key] = value return None return self._data[key] def remove(self, key): return self._data.pop(key, None) def replace(self, key, old_value=None, new_value=None): if new_value is None: if key in self._data: old = self._data[key] self._data[key] = old_value return old return None if key in self._data and self._data[key] == old_value: self._data[key] = new_value return True return False def size(self) -> int: return len(self._data) def values(self): return [self._data[k] for k in self._sorted_keys()] def navigableKeySet(self): return self._sorted_keys() def descendingKeySet(self): return list(reversed(self._sorted_keys())) def descendingMap(self) -> 'TreeMap': result = TreeMap(self._comparator) for k in reversed(self._sorted_keys()): result._data[k] = self._data[k] return result def equals(self, other) -> bool: if isinstance(other, TreeMap): return self._data == other._data return False def hashCode(self) -> int: h = 0 for k, v in self._data.items(): h = (h + (hash(k) ^ hash(v))) & 0x7FFFFFFF return h def toString(self) -> str: items = ", ".join(f"{k}={v}" for k in self._data.items()) return f"{{{items}}}" def __len__(self): return len(self._data) def __getitem__(self, key): return self._data[key] def __setitem__(self, key, value): self._data[key] = value def __delitem__(self, key): del self._data[key] def __iter__(self): return iter(self._sorted_keys()) def __repr__(self): return self.toString() def __eq__(self, other): return self.equals(other) # ============================================================ # HashSet # ============================================================ class HashSet(Stub): """java.util.HashSet — backed by Python set""" def __init__(self, c=None): super().__init__() if c is None: self._data: set = set() elif isinstance(c, _IterableABC): self._data = set(c) else: self._data = set() def add(self, obj) -> bool: if obj in self._data: return False self._data.add(obj) return True def addAll(self, c) -> bool: old_size = len(self._data) if isinstance(c, HashSet): self._data.update(c._data) elif isinstance(c, set): self._data.update(c) else: self._data.update(c) return len(self._data) != old_size def clear(self) -> None: self._data.clear() def clone(self) -> 'HashSet': return HashSet(self._data) def contains(self, obj) -> bool: return obj in self._data def containsAll(self, c) -> bool: if isinstance(c, HashSet): return all(x in self._data for x in c._data) return all(x in self._data for x in c) def isEmpty(self) -> bool: return len(self._data) == 0 def iterator(self) -> Iterator: return Iterator(list(self._data)) def remove(self, obj) -> bool: if obj in self._data: self._data.remove(obj) return True return False def removeAll(self, c) -> bool: old_size = len(self._data) if isinstance(c, HashSet): self._data.difference_update(c._data) else: self._data.difference_update(c) return len(self._data) != old_size def retainAll(self, c) -> bool: old_size = len(self._data) if isinstance(c, HashSet): self._data.intersection_update(c._data) else: self._data.intersection_update(c) return len(self._data) != old_size def size(self) -> int: return len(self._data) def toArray(self, a=None): items = list(self._data) if a is None: return items if len(a) < len(items): return items for i, v in enumerate(items): a[i] = v if len(items) < len(a): a[len(items)] = None return a def forEach(self, action) -> None: for item in list(self._data): action(item) def equals(self, other) -> bool: if isinstance(other, HashSet): return self._data == other._data return False def hashCode(self) -> int: h = 0 for v in self._data: h = (h + hash(v)) & 0x7FFFFFFF return h def toString(self) -> str: items = ", ".join(str(x) for x in self._data) return f"[{items}]" def __len__(self): return len(self._data) def __iter__(self): return iter(self._data) def __contains__(self, obj): return obj in self._data def __repr__(self): return self.toString() def __eq__(self, other): return self.equals(other) # ============================================================ # LinkedHashSet # ============================================================ class LinkedHashSet(HashSet): """java.util.LinkedHashSet — ordered set (preserves insertion order)""" def __init__(self, c=None): # dict keys preserve insertion order in Python 3.7+ self._order: Dict[Any, None] = {} if c is not None: if isinstance(c, _IterableABC): for item in c: self._order[item] = None self._data = set(self._order.keys()) def add(self, obj) -> bool: if obj in self._order: return False self._order[obj] = None self._data.add(obj) return True def remove(self, obj) -> bool: if obj in self._order: del self._order[obj] self._data.discard(obj) return True return False def clear(self) -> None: self._order.clear() self._data.clear() def iterator(self) -> Iterator: return Iterator(list(self._order.keys())) def toArray(self, a=None): items = list(self._order.keys()) if a is None: return items if len(a) < len(items): return items for i, v in enumerate(items): a[i] = v if len(items) < len(a): a[len(items)] = None return a def forEach(self, action) -> None: for item in list(self._order.keys()): action(item) def __iter__(self): return iter(self._order.keys()) # ============================================================ # TreeSet # ============================================================ class TreeSet(Stub): """java.util.TreeSet — sorted set""" def __init__(self, comparator=None, c=None): super().__init__() self._data: set = set() self._comparator = comparator if c is not None: if isinstance(c, _IterableABC): self._data = set(c) def _sorted(self): key_fn = self._comparator if self._comparator else None return sorted(self._data, key=key_fn) def add(self, obj) -> bool: if obj in self._data: return False self._data.add(obj) return True def addAll(self, c) -> bool: old_size = len(self._data) if isinstance(c, TreeSet): self._data.update(c._data) else: self._data.update(c) return len(self._data) != old_size def ceiling(self, obj): sorted_items = self._sorted() for item in sorted_items: if (self._comparator(item, obj) >= 0 if self._comparator else item >= obj): return item return None def floor(self, obj): sorted_items = self._sorted() for item in reversed(sorted_items): if (self._comparator(item, obj) <= 0 if self._comparator else item <= obj): return item return None def higher(self, obj): sorted_items = self._sorted() for item in sorted_items: if (self._comparator(item, obj) > 0 if self._comparator else item > obj): return item return None def lower(self, obj): sorted_items = self._sorted() for item in reversed(sorted_items): if (self._comparator(item, obj) < 0 if self._comparator else item < obj): return item return None def clear(self) -> None: self._data.clear() def clone(self) -> 'TreeSet': return TreeSet(self._comparator, self._data) def comparator(self): return self._comparator def contains(self, obj) -> bool: return obj in self._data def containsAll(self, c) -> bool: if isinstance(c, TreeSet): return all(x in self._data for x in c._data) return all(x in self._data for x in c) def first(self): if not self._data: raise NoSuchElementException() return self._sorted()[0] def last(self): if not self._data: raise NoSuchElementException() return self._sorted()[-1] def pollFirst(self): if not self._data: return None val = self._sorted()[0] self._data.discard(val) return val def pollLast(self): if not self._data: return None val = self._sorted()[-1] self._data.discard(val) return val def headSet(self, to_element, inclusive: bool = False) -> 'TreeSet': result = TreeSet(self._comparator) for item in self._data: cmp = self._comparator(item, to_element) if self._comparator else (item < to_element) if cmp or (inclusive and item == to_element): result._data.add(item) return result def tailSet(self, from_element, inclusive: bool = True) -> 'TreeSet': result = TreeSet(self._comparator) for item in self._data: cmp = self._comparator(item, from_element) if self._comparator else (item > from_element) if cmp or (inclusive and item == from_element): result._data.add(item) return result def subSet(self, from_element, to_element, from_inclusive: bool = True, to_inclusive: bool = False) -> 'TreeSet': result = TreeSet(self._comparator) for item in self._data: cmp_from = self._comparator(item, from_element) if self._comparator else ( item >= from_element if from_inclusive else item > from_element) cmp_to = self._comparator(item, to_element) if self._comparator else ( item <= to_element if to_inclusive else item < to_element) if cmp_from and cmp_to: result._data.add(item) return result def descendingIterator(self) -> Iterator: return Iterator(reversed(self._sorted())) def descendingSet(self) -> 'TreeSet': result = TreeSet(self._comparator) result._data = set(self._data) return result def isEmpty(self) -> bool: return len(self._data) == 0 def iterator(self) -> Iterator: return Iterator(self._sorted()) def remove(self, obj) -> bool: if obj in self._data: self._data.discard(obj) return True return False def removeAll(self, c) -> bool: old_size = len(self._data) if isinstance(c, TreeSet): self._data.difference_update(c._data) else: self._data.difference_update(c) return len(self._data) != old_size def retainAll(self, c) -> bool: old_size = len(self._data) if isinstance(c, TreeSet): self._data.intersection_update(c._data) else: self._data.intersection_update(c) return len(self._data) != old_size def size(self) -> int: return len(self._data) def toArray(self, a=None): items = self._sorted() if a is None: return items if len(a) < len(items): return items for i, v in enumerate(items): a[i] = v if len(items) < len(a): a[len(items)] = None return a def forEach(self, action) -> None: for item in self._sorted(): action(item) def equals(self, other) -> bool: if isinstance(other, TreeSet): return self._data == other._data return False def hashCode(self) -> int: h = 0 for v in self._data: h = (h + hash(v)) & 0x7FFFFFFF return h def toString(self) -> str: items = ", ".join(str(x) for x in self._sorted()) return f"[{items}]" def __len__(self): return len(self._data) def __iter__(self): return iter(self._sorted()) def __contains__(self, obj): return obj in self._data def __repr__(self): return self.toString() def __eq__(self, other): return self.equals(other) # ============================================================ # Collections # ============================================================ class Collections: """java.util.Collections — static utility methods""" EMPTY_LIST = [] EMPTY_SET = set() EMPTY_MAP = {} @staticmethod def sort(data, key=None, reverse: bool = False) -> None: if key is not None: if isinstance(data, ArrayList): data._data.sort(key=key, reverse=reverse) elif isinstance(data, Vector): data._data.sort(key=key, reverse=reverse) else: data.sort(key=key, reverse=reverse) else: data.sort(reverse=reverse) @staticmethod def reverse(data) -> None: if isinstance(data, ArrayList): data._data.reverse() elif isinstance(data, Vector): data._data.reverse() else: data.reverse() @staticmethod def shuffle(data, rnd: _typing.Optional['Random'] = None) -> None: if isinstance(data, ArrayList): lst = data._data elif isinstance(data, Vector): lst = data._data else: lst = data if rnd: _py_random.shuffle(lst) else: _py_random.shuffle(lst) @staticmethod def swap(data, i: int, j: int) -> None: if isinstance(data, ArrayList): data._data[i], data._data[j] = data._data[j], data._data[i] elif isinstance(data, Vector): data._data[i], data._data[j] = data._data[j], data._data[i] else: data[i], data[j] = data[j], data[i] @staticmethod def fill(data, obj) -> None: if isinstance(data, ArrayList): for i in range(len(data._data)): data._data[i] = obj elif isinstance(data, Vector): for i in range(len(data._data)): data._data[i] = obj else: for i in range(len(data)): data[i] = obj @staticmethod def copy(dest, src) -> None: if isinstance(dest, ArrayList) and isinstance(src, ArrayList): dest._data[:len(src._data)] = src._data[:] elif isinstance(dest, Vector) and isinstance(src, Vector): dest._data[:len(src._data)] = src._data[:] else: dest[:len(src)] = src[:] @staticmethod def min(coll, comp=None): if comp: return min(coll, key=comp) return min(coll) @staticmethod def max(coll, comp=None): if comp: return max(coll, key=comp) return max(coll) @staticmethod def rotate(data, distance: int) -> None: if isinstance(data, ArrayList): lst = data._data elif isinstance(data, Vector): lst = data._data else: lst = data n = len(lst) if n == 0: return d = distance % n lst[:] = lst[-d:] + lst[:-d] @staticmethod def indexOfSubList(source, target) -> int: if isinstance(source, ArrayList): src = source._data else: src = list(source) if isinstance(target, ArrayList): tgt = target._data else: tgt = list(target) for i in range(len(src) - len(tgt) + 1): if src[i:i + len(tgt)] == tgt: return i return -1 @staticmethod def lastIndexOfSubList(source, target) -> int: if isinstance(source, ArrayList): src = source._data else: src = list(source) if isinstance(target, ArrayList): tgt = target._data else: tgt = list(target) for i in range(len(src) - len(tgt), -1, -1): if src[i:i + len(tgt)] == tgt: return i return -1 @staticmethod def replaceAll(data, old_val, new_val) -> bool: if isinstance(data, ArrayList): lst = data._data elif isinstance(data, Vector): lst = data._data else: lst = data found = False for i, v in enumerate(lst): if v == old_val: lst[i] = new_val found = True return found @staticmethod def binarySearch(data, key): if isinstance(data, ArrayList): lst = data._data else: lst = list(data) idx = _bisect.bisect_left(lst, key) if idx < len(lst) and lst[idx] == key: return idx return -1 @staticmethod def disjoint(c1, c2) -> bool: set1 = set(c1) set2 = set(c2) return set1.isdisjoint(set2) @staticmethod def frequency(c, obj) -> int: count = 0 for item in c: if item == obj: count += 1 return count @staticmethod def nCopies(n: int, obj) -> list: return [obj] * n @staticmethod def singleton(obj) -> set: return {obj} @staticmethod def singletonList(obj) -> list: return [obj] @staticmethod def singletonMap(key, value) -> dict: return {key: value} @staticmethod def unmodifiableList(data) -> list: if isinstance(data, ArrayList): return tuple(data._data) return tuple(data) @staticmethod def unmodifiableSet(data) -> frozenset: if isinstance(data, HashSet): return frozenset(data._data) return frozenset(data) @staticmethod def unmodifiableMap(data) -> dict: if isinstance(data, HashMap): return dict(data._data) return dict(data) @staticmethod def synchronizedList(data): lock = _threading.Lock() class _SyncList: def __init__(self, lst): self._lock = lock self._lst = lst def __getattr__(self, name): with self._lock: return getattr(self._lst, name) def add(self, obj): with self._lock: return self._lst.add(obj) def get(self, idx): with self._lock: return self._lst[idx] def set(self, idx, val): with self._lock: old = self._lst[idx] self._lst[idx] = val return old def remove(self, obj): with self._lock: return self._lst.remove(obj) def size(self): with self._lock: return len(self._lst) def __len__(self): with self._lock: return len(self._lst) def __getitem__(self, idx): with self._lock: return self._lst[idx] def __setitem__(self, idx, val): with self._lock: self._lst[idx] = val def __iter__(self): with self._lock: return iter(list(self._lst)) return _SyncList(data) @staticmethod def synchronizedSet(data): lock = _threading.Lock() class _SyncSet: def __init__(self, s): self._lock = lock self._s = s def add(self, obj): with self._lock: return self._s.add(obj) def remove(self, obj): with self._lock: return self._s.remove(obj) def __contains__(self, obj): with self._lock: return obj in self._s def __iter__(self): with self._lock: return iter(list(self._s)) def __len__(self): with self._lock: return len(self._s) return _SyncSet(data) @staticmethod def synchronizedMap(data): lock = _threading.Lock() class _SyncMap: def __init__(self, m): self._lock = lock self._m = m def put(self, k, v): with self._lock: return self._m.put(k, v) def get(self, k): with self._lock: return self._m.get(k) def remove(self, k): with self._lock: return self._m.remove(k) def __getitem__(self, k): with self._lock: return self._m[k] def __setitem__(self, k, v): with self._lock: self._m[k] = v def __contains__(self, k): with self._lock: return k in self._m def __len__(self): with self._lock: return len(self._m) def keys(self): with self._lock: return list(self._m.keys()) return _SyncMap(data) @staticmethod def enumaration(c) -> Enumeration: return Enumeration(c) @staticmethod def list(enum: Enumeration) -> ArrayList: items = [] while enum.hasMoreElements(): items.append(enum.nextElement()) return ArrayList(items) @staticmethod def newSetFromMap(m) -> HashSet: class _SetFromMap(HashSet): def __init__(self, backing_map): super().__init__() self._backing = backing_map def add(self, obj): return self._backing.put(obj, True) is None def iterator(self): return Iterator(self._backing.keySet()) def size(self): return self._backing.size() def remove(self, obj): return self._backing.remove(obj) is not None def contains(self, obj): return self._backing.containsKey(obj) def clear(self): self._backing.clear() return _SetFromMap(m) @staticmethod def asLifoQueue(deque) -> 'Collections._LifoQueue': class _LifoQueue: def __init__(self, dq): self._dq = dq def add(self, e): self._dq.addFirst(e) return True def offer(self, e): return self.add(e) def remove(self): if len(self._dq) == 0: raise NoSuchElementException() return self._dq.removeFirst() def poll(self): return self._dq.pollFirst() def element(self): if len(self._dq) == 0: raise NoSuchElementException() return self._dq.getFirst() def peek(self): return self._dq.peekFirst() def size(self): return self._dq.size() def isEmpty(self): return self._dq.isEmpty() return _LifoQueue(deque) # ============================================================ # Arrays # ============================================================ class Arrays: """java.util.Arrays — static utility methods""" @staticmethod def asList(*args) -> ArrayList: if len(args) == 1 and isinstance(args[0], (list, tuple)): return ArrayList(args[0]) return ArrayList(list(args)) @staticmethod def sort(a, from_index: int = 0, to_index: int = None) -> None: if to_index is None: a.sort() else: a[from_index:to_index] = sorted(a[from_index:to_index]) @staticmethod def parallelSort(a, from_index: int = 0, to_index: int = None) -> None: Arrays.sort(a, from_index, to_index) @staticmethod def binarySearch(a, key, from_index: int = 0, to_index: int = None) -> int: if to_index is None: lst = a else: lst = a[from_index:to_index] idx = _bisect.bisect_left(lst, key) if idx < len(lst) and lst[idx] == key: return idx + from_index return -(idx + from_index + 1) @staticmethod def fill(a, val, from_index: int = 0, to_index: int = None) -> None: if to_index is None: for i in range(len(a)): a[i] = val else: for i in range(from_index, to_index): a[i] = val @staticmethod def copyOf(original, new_length: int) -> list: return list(original[:new_length]) + [None] * max(0, new_length - len(original)) @staticmethod def copyOfRange(original, from_index: int, to_index: int) -> list: return list(original[from_index:to_index]) @staticmethod def equals(a, b) -> bool: if len(a) != len(b): return False return all(x == y for x, y in zip(a, b)) @staticmethod def deepEquals(a, b) -> bool: if len(a) != len(b): return False return all(_deep_eq(x, y) for x, y in zip(a, b)) @staticmethod def hashCode(a) -> int: if a is None: return 0 h = 1 for v in a: h = (31 * h + hash(v)) & 0x7FFFFFFF return h @staticmethod def deepHashCode(a) -> int: if a is None: return 0 h = 1 for v in a: if isinstance(v, (list, tuple)): h = (31 * h + Arrays.deepHashCode(v)) & 0x7FFFFFFF else: h = (31 * h + hash(v)) & 0x7FFFFFFF return h @staticmethod def toString(a) -> str: if a is None: return "null" return "[" + ", ".join(str(x) for x in a) + "]" @staticmethod def deepToString(a) -> str: if a is None: return "null" return "[" + ", ".join(_deep_str(x) for x in a) + "]" @staticmethod def stream(a) -> 'Arrays._ArrayStream': class _ArrayStream: def __init__(self, arr): self._arr = arr self._idx = 0 def filter(self, pred): return _ArrayStream([x for x in self._arr if pred(x)]) def map(self, func): return _ArrayStream([func(x) for x in self._arr]) def forEach(self, action): for x in self._arr: action(x) def toArray(self): return list(self._arr) def count(self): return len(self._arr) return _ArrayStream(a) @staticmethod def setAll(a, generator) -> None: for i in range(len(a)): a[i] = generator(i) @staticmethod def parallelSetAll(a, generator) -> None: Arrays.setAll(a, generator) @staticmethod def spliterator(a) -> Iterator: return Iterator(a) def _deep_eq(x, y) -> bool: if isinstance(x, (list, tuple)) and isinstance(y, (list, tuple)): return Arrays.deepEquals(x, y) return x == y def _deep_str(x) -> str: if isinstance(x, (list, tuple)): return Arrays.deepToString(x) return str(x) # ============================================================ # Date # ============================================================ class Date(Stub): """java.util.Date — wraps Python datetime""" def __init__(self, *args): super().__init__() if len(args) == 0: self._dt = _datetime.datetime.now() elif len(args) == 1: if isinstance(args[0], (int, float)): self._dt = _datetime.datetime.fromtimestamp(args[0] / 1000.0) elif isinstance(args[0], str): self._dt = _datetime.datetime.fromisoformat(args[0]) elif isinstance(args[0], _datetime.datetime): self._dt = args[0] elif isinstance(args[0], Date): self._dt = args[0]._dt else: self._dt = _datetime.datetime.now() elif len(args) >= 6: year = args[0] - 1900 month = args[1] day = args[2] hour = args[3] if len(args) > 3 else 0 minute = args[4] if len(args) > 4 else 0 second = args[5] if len(args) > 5 else 0 self._dt = _datetime.datetime(year + 1900, month + 1, day, hour, minute, second) else: self._dt = _datetime.datetime.now() def getTime(self) -> int: return int(self._dt.timestamp() * 1000) def setTime(self, time_millis: int) -> None: self._dt = _datetime.datetime.fromtimestamp(time_millis / 1000.0) def before(self, when: 'Date') -> bool: return self._dt < when._dt def after(self, when: 'Date') -> bool: return self._dt > when._dt def compareTo(self, another: 'Date') -> int: return (self._dt > another._dt) - (self._dt < another._dt) def equals(self, other) -> bool: if isinstance(other, Date): return self._dt == other._dt return False def hashCode(self) -> int: return hash(self._dt) & 0x7FFFFFFF def toString(self) -> str: return self._dt.strftime("%a %b %d %H:%M:%S %z %Y") def clone(self) -> 'Date': return Date(self._dt) def getYear(self) -> int: return self._dt.year - 1900 def getMonth(self) -> int: return self._dt.month - 1 def getDay(self) -> int: return self._dt.weekday() def getHours(self) -> int: return self._dt.hour def getMinutes(self) -> int: return self._dt.minute def getSeconds(self) -> int: return self._dt.second def getDate(self) -> int: return self._dt.day def setYear(self, year: int) -> None: self._dt = self._dt.replace(year=year + 1900) def setMonth(self, month: int) -> None: self._dt = self._dt.replace(month=month + 1) def setDate(self, date: int) -> None: self._dt = self._dt.replace(day=date) def setHours(self, hours: int) -> None: self._dt = self._dt.replace(hour=hours) def setMinutes(self, minutes: int) -> None: self._dt = self._dt.replace(minute=minutes) def setSeconds(self, seconds: int) -> None: self._dt = self._dt.replace(second=seconds) def toGMTString(self) -> str: return self._dt.strftime("%d %b %Y %H:%M:%S GMT") def toLocaleString(self) -> str: return self._dt.strftime("%Y-%m-%d %H:%M:%S") @staticmethod def parse(s: str) -> 'Date': try: return Date(_datetime.datetime.fromisoformat(s)) except ValueError: return Date() @staticmethod def fromInstant(instant) -> 'Date': return Date(instant.toEpochMilli()) def toInstant(self): return self._dt def __str__(self): return self.toString() def __repr__(self): return f"Date({self.getTime()})" # ============================================================ # Calendar / GregorianCalendar # ============================================================ class Calendar(Stub): """java.util.Calendar — wraps Python datetime with Java field system""" # Field constants YEAR = 1 MONTH = 2 DAY_OF_MONTH = 5 DAY_OF_YEAR = 6 DAY_OF_WEEK = 7 DAY_OF_WEEK_IN_MONTH = 8 AM_PM = 9 HOUR = 10 HOUR_OF_DAY = 11 MINUTE = 12 SECOND = 13 MILLISECOND = 14 WEEK_OF_MONTH = 15 WEEK_OF_YEAR = 16 ERA = 17 ZONE_OFFSET = 18 DST_OFFSET = 19 FIELD_COUNT = 20 # Day of week constants SUNDAY = 1 MONDAY = 2 TUESDAY = 3 WEDNESDAY = 4 THURSDAY = 5 FRIDAY = 6 SATURDAY = 7 # Month constants JANUARY = 0 FEBRUARY = 1 MARCH = 2 APRIL = 3 MAY = 4 JUNE = 5 JULY = 6 AUGUST = 7 SEPTEMBER = 8 OCTOBER = 9 NOVEMBER = 10 DECEMBER = 11 UNDECIMBER = 12 # AM/PM AM = 0 PM = 1 def __init__(self): super().__init__() self._dt = _datetime.datetime.now() self._fields: Dict[int, int] = {} self._is_set: Dict[int, bool] = {} self._lenient = True self._first_day_of_week = Calendar.SUNDAY self._minimal_days_in_first_week = 1 self._timezone = _datetime.timezone.utc self._set_fields_from_dt() def _set_fields_from_dt(self) -> None: self._fields[Calendar.YEAR] = self._dt.year self._fields[Calendar.MONTH] = self._dt.month - 1 self._fields[Calendar.DAY_OF_MONTH] = self._dt.day self._fields[Calendar.DAY_OF_YEAR] = self._dt.timetuple().tm_yday self._fields[Calendar.DAY_OF_WEEK] = self._dt.isoweekday() % 7 + 1 self._fields[Calendar.HOUR] = self._dt.hour % 12 self._fields[Calendar.HOUR_OF_DAY] = self._dt.hour self._fields[Calendar.MINUTE] = self._dt.minute self._fields[Calendar.SECOND] = self._dt.second self._fields[Calendar.MILLISECOND] = self._dt.microsecond // 1000 self._fields[Calendar.AM_PM] = Calendar.AM if self._dt.hour < 12 else Calendar.PM self._fields[Calendar.WEEK_OF_YEAR] = self._dt.isocalendar()[1] self._fields[Calendar.ERA] = 1 # AD = 1 def get(self, field: int) -> int: return self._fields.get(field, 0) def set(self, field: int, value: int) -> None: self._fields[field] = value self._is_set[field] = True def setTime(self, date: 'Date') -> None: self._dt = date._dt self._set_fields_from_dt() def getTime(self) -> Date: return Date(self._dt) def getTimeInMillis(self) -> int: return int(self._dt.timestamp() * 1000) def setTimeInMillis(self, millis: int) -> None: self._dt = _datetime.datetime.fromtimestamp(millis / 1000.0) self._set_fields_from_dt() def add(self, field: int, amount: int) -> None: if field == Calendar.YEAR: self._dt = self._dt.replace(year=self._dt.year + amount) elif field == Calendar.MONTH: new_month = self._dt.month - 1 + amount new_year = self._dt.year + new_month // 12 new_month = new_month % 12 try: self._dt = self._dt.replace(year=new_year, month=new_month + 1) except ValueError: self._dt = self._dt.replace(year=new_year, month=new_month + 1, day=28) elif field == Calendar.DAY_OF_MONTH: self._dt += _datetime.timedelta(days=amount) elif field == Calendar.HOUR_OF_DAY or field == Calendar.HOUR: self._dt += _datetime.timedelta(hours=amount) elif field == Calendar.MINUTE: self._dt += _datetime.timedelta(minutes=amount) elif field == Calendar.SECOND: self._dt += _datetime.timedelta(seconds=amount) elif field == Calendar.MILLISECOND: self._dt += _datetime.timedelta(milliseconds=amount) elif field == Calendar.WEEK_OF_YEAR or field == Calendar.WEEK_OF_MONTH: self._dt += _datetime.timedelta(weeks=amount) self._set_fields_from_dt() def roll(self, field: int, amount: int) -> None: if field == Calendar.MONTH: old_month = self._dt.month new_month = ((old_month - 1 + amount) % 12) + 1 try: self._dt = self._dt.replace(month=new_month) except ValueError: self._dt = self._dt.replace(month=new_month, day=28) elif field == Calendar.DAY_OF_MONTH: import calendar as _cal max_day = _cal.monthrange(self._dt.year, self._dt.month)[1] new_day = ((self._dt.day - 1 + amount) % max_day) + 1 self._dt = self._dt.replace(day=new_day) else: self.add(field, amount) self._set_fields_from_dt() def before(self, when: 'Calendar') -> bool: return self._dt < when._dt def after(self, when: 'Calendar') -> bool: return self._dt > when._dt def compareTo(self, another: 'Calendar') -> int: return (self._dt > another._dt) - (self._dt < another._dt) def equals(self, other) -> bool: if isinstance(other, Calendar): return self._dt == other._dt return False def hashCode(self) -> int: return hash(self._dt) & 0x7FFFFFFF def toString(self) -> str: return str(self._dt) def isLenient(self) -> bool: return self._lenient def setLenient(self, lenient: bool) -> None: self._lenient = lenient def getFirstDayOfWeek(self) -> int: return self._first_day_of_week def setFirstDayOfWeek(self, value: int) -> None: self._first_day_of_week = value def getMinimalDaysInFirstWeek(self) -> int: return self._minimal_days_in_first_week def setMinimalDaysInFirstWeek(self, value: int) -> None: self._minimal_days_in_first_week = value def getActualMaximum(self, field: int) -> int: import calendar as _cal if field == Calendar.DAY_OF_MONTH: return _cal.monthrange(self._dt.year, self._dt.month)[1] if field == Calendar.DAY_OF_YEAR: return 366 if self._dt.year % 4 == 0 and (self._dt.year % 100 != 0 or self._dt.year % 400 == 0) else 365 if field == Calendar.MONTH: return 11 if field == Calendar.HOUR: return 11 if field == Calendar.HOUR_OF_DAY: return 23 if field == Calendar.MINUTE: return 59 if field == Calendar.SECOND: return 59 if field == Calendar.MILLISECOND: return 999 return 0 def getActualMinimum(self, field: int) -> int: return 0 def getDisplayName(self, field: int, style: int, locale: 'Locale') -> str: return str(self.get(field)) @staticmethod def getInstance() -> 'GregorianCalendar': return GregorianCalendar() class GregorianCalendar(Calendar): """java.util.GregorianCalendar""" BC = 0 AD = 1 def __init__(self, *args): super().__init__() if len(args) == 0: self._dt = _datetime.datetime.now() elif len(args) == 3: year, month, day = args self._dt = _datetime.datetime(year, month + 1, day) elif len(args) >= 5: year, month, day, hour, minute = args[:5] second = args[5] if len(args) > 5 else 0 self._dt = _datetime.datetime(year, month + 1, day, hour, minute, second) else: self._dt = _datetime.datetime.now() self._set_fields_from_dt() def isLeapYear(self, year: int) -> bool: return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 def getGreatestMinimum(self, field: int) -> int: return self.getActualMinimum(field) def getLeastMaximum(self, field: int) -> int: return self.getActualMaximum(field) def getMaximum(self, field: int) -> int: if field == Calendar.DAY_OF_MONTH: return 31 if field == Calendar.DAY_OF_YEAR: return 366 if field == Calendar.MONTH: return 11 return self.getActualMaximum(field) def getMinimum(self, field: int) -> int: return 0 # ============================================================ # UUID # ============================================================ class UUID(Stub): """java.util.UUID — wraps Python uuid module""" def __init__(self, most_sig_bits: int, least_sig_bits: int): super().__init__() self._most_sig_bits = most_sig_bits & 0xFFFFFFFFFFFFFFFF self._least_sig_bits = least_sig_bits & 0xFFFFFFFFFFFFFFFF # Rebuild a Python UUID from the bits for string representation hex_str = f"{self._most_sig_bits:016x}{self._least_sig_bits:016x}" self._uuid = _uuid.UUID(hex_str) @staticmethod def randomUUID() -> 'UUID': u = _uuid.uuid4() most = u.int >> 64 least = u.int & 0xFFFFFFFFFFFFFFFF return UUID(most, least) @staticmethod def nameUUIDFromBytes(name: bytes) -> 'UUID': u = _uuid.uuid3(_uuid.NAMESPACE_DNS, name.decode('utf-8', errors='replace')) most = u.int >> 64 least = u.int & 0xFFFFFFFFFFFFFFFF return UUID(most, least) @staticmethod def fromString(name: str) -> 'UUID': u = _uuid.UUID(name) most = u.int >> 64 least = u.int & 0xFFFFFFFFFFFFFFFF return UUID(most, least) def getMostSignificantBits(self) -> int: return self._most_sig_bits def getLeastSignificantBits(self) -> int: return self._least_sig_bits def version(self) -> int: return self._uuid.version def variant(self) -> int: return self._uuid.variant def timestamp(self) -> int: if self.version() != 1: raise UnsupportedOperationException("Not a time-based UUID") return self._uuid.time def clockSequence(self) -> int: if self.version() != 1: raise UnsupportedOperationException("Not a time-based UUID") return self._uuid.clock_seq def node(self) -> int: if self.version() != 1: raise UnsupportedOperationException("Not a time-based UUID") return self._uuid.node def compareTo(self, other: 'UUID') -> int: return (self._uuid.int > other._uuid.int) - (self._uuid.int < other._uuid.int) def equals(self, other) -> bool: if isinstance(other, UUID): return self._uuid == other._uuid return False def hashCode(self) -> int: return hash(self._uuid) & 0x7FFFFFFF def toString(self) -> str: return str(self._uuid) def __str__(self): return str(self._uuid) def __repr__(self): return f"UUID({str(self._uuid)})" # ============================================================ # StringTokenizer # ============================================================ class StringTokenizer(Stub): """java.util.StringTokenizer — simple tokenizer""" def __init__(self, s: str, delim: str = " \t\n\r\f", return_delims: bool = False): super().__init__() self._str = str(s) self._delim = delim self._return_delims = return_delims self._tokens = self._tokenize() self._index = 0 def _tokenize(self): if self._return_delims: tokens = [] buf = "" for ch in self._str: if ch in self._delim: if buf: tokens.append(buf) buf = "" tokens.append(ch) else: buf += ch if buf: tokens.append(buf) return tokens import re as _re pattern = f"[{_re.escape(self._delim)}]+" return [t for t in _re.split(pattern, self._str) if t] def countTokens(self) -> int: return len(self._tokens) def hasMoreTokens(self) -> bool: return self._index < len(self._tokens) def nextToken(self, delim: str = None) -> str: if delim is not None: self._delim = delim remaining = self._str[self._index:] st = StringTokenizer(remaining, delim, self._return_delims) self._tokens = st._tokens self._index = 0 if not self.hasMoreTokens(): raise NoSuchElementException() tok = self._tokens[self._index] self._index += 1 return tok def hasMoreElements(self) -> bool: return self.hasMoreTokens() def nextElement(self): return self.nextToken() def __iter__(self): return self def __next__(self): if not self.hasMoreTokens(): raise StopIteration return self.nextToken() # ============================================================ # Optional # ============================================================ class Optional(Stub): """java.util.Optional — wraps value or None""" def __init__(self, value=None): super().__init__() self._value = value @staticmethod def empty() -> 'Optional': return Optional(None) @staticmethod def of(value) -> 'Optional': if value is None: raise TypeError("value is null") return Optional(value) @staticmethod def ofNullable(value) -> 'Optional': return Optional(value) def get(self): if self._value is None: raise NoSuchElementException("No value present") return self._value def isPresent(self) -> bool: return self._value is not None def isEmpty(self) -> bool: return self._value is None def ifPresent(self, consumer) -> None: if self._value is not None: consumer(self._value) def ifPresentOrElse(self, action, empty_action) -> None: if self._value is not None: action(self._value) else: empty_action() def filter(self, predicate) -> 'Optional': if self._value is None: return self return Optional.ofNullable(self._value) if predicate(self._value) else Optional.empty() def map(self, mapper) -> 'Optional': if self._value is None: return Optional.empty() return Optional.ofNullable(mapper(self._value)) def flatMap(self, mapper) -> 'Optional': if self._value is None: return Optional.empty() return mapper(self._value) def orElse(self, other): return self._value if self._value is not None else other def orElseGet(self, supplier): if self._value is not None: return self._value return supplier() def orElseThrow(self, exception_supplier=None): if self._value is not None: return self._value if exception_supplier: raise exception_supplier() raise NoSuchElementException("No value present") def stream(self): if self._value is not None: return [self._value] return [] def equals(self, other) -> bool: if isinstance(other, Optional): return self._value == other._value return False def hashCode(self) -> int: return hash(self._value) & 0x7FFFFFFF if self._value is not None else 0 def toString(self) -> str: if self._value is None: return "Optional.empty" return f"Optional[{self._value}]" def __str__(self): return self.toString() def __repr__(self): return self.toString() def __bool__(self): return self._value is not None # ============================================================ # Random # ============================================================ class Random(Stub): """java.util.Random — wraps Python random module""" def __init__(self, seed: _typing.Optional[int] = None): super().__init__() self._rng = _py_random.Random(seed) def setSeed(self, seed: int) -> None: self._rng.seed(seed) def nextInt(self, bound: _typing.Optional[int] = None) -> int: if bound is None: return self._rng.randint(-2147483648, 2147483647) if bound <= 0: raise IllegalArgumentException("bound must be positive") return self._rng.randrange(0, bound) def nextLong(self) -> int: return (self._rng.randint(-2147483648, 2147483647) << 32) | self._rng.randint(0, 0xFFFFFFFF) def nextBoolean(self) -> bool: return self._rng.random() < 0.5 def nextFloat(self) -> float: return self._rng.random() def nextDouble(self) -> float: return self._rng.random() def nextGaussian(self) -> float: return self._rng.gauss(0.0, 1.0) def nextBytes(self, bytes_arr: bytearray) -> None: for i in range(len(bytes_arr)): bytes_arr[i] = self._rng.randint(0, 255) def next(self, bits: int) -> int: return self._rng.getrandbits(bits) & ((1 << bits) - 1) @staticmethod def create() -> 'Random': return Random() # ============================================================ # Properties # ============================================================ class Properties(HashMap): """java.util.Properties — extends Hashtable-like dict with load/store""" def __init__(self, defaults: 'Properties' = None): super().__init__() self._defaults = defaults def setProperty(self, key: str, value: str) -> None: self.put(str(key), str(value)) def getProperty(self, key: str, default_value: str = None) -> _typing.Optional[str]: val = self._data.get(str(key)) if val is not None: return str(val) if self._defaults is not None: return self._defaults.getProperty(key, default_value) return default_value def load(self, in_stream) -> None: if isinstance(in_stream, (str, bytes)): lines = in_stream.splitlines() if isinstance(in_stream, str) else in_stream.decode('utf-8').splitlines() else: lines = in_stream.read().splitlines() if hasattr(in_stream, 'read') else in_stream.splitlines() for line in lines: line = line.strip() if not line or line.startswith('#') or line.startswith('!'): continue if '=' in line: key, val = line.split('=', 1) elif ':' in line: key, val = line.split(':', 1) else: key = line val = "" key = key.strip() val = val.strip() self._data[key] = val def store(self, out_stream, comments: str = None) -> None: lines = [] if comments: lines.append(f"#{comments}") lines.append(f"# {_datetime.datetime.now().isoformat()}") for k, v in self._data.items(): escaped_val = str(v).replace("\\", "\\\\").replace(" ", "\\ ") lines.append(f"{k}={escaped_val}") content = "\n".join(lines) + "\n" if isinstance(out_stream, _io.IOBase): out_stream.write(content) else: out_stream.write(content) # type: ignore def list(self, out_stream) -> None: for k, v in self._data.items(): out_stream.write(f"{k}={v}\n") def propertyNames(self): return Iterator(self._data.keys()) def stringPropertyNames(self) -> set: names = set() for k in self._data.keys(): if isinstance(k, str): names.add(k) if self._defaults: names.update(self._defaults.stringPropertyNames()) return names def loadFromXML(self, in_stream) -> None: import xml.etree.ElementTree as _ET tree = _ET.parse(in_stream) root = tree.getroot() for entry in root.findall('entry'): key = entry.get('key', '') self._data[key] = entry.text or '' def storeToXML(self, out_stream, comment: str = None) -> None: import xml.etree.ElementTree as _ET root = _ET.Element('properties') if comment: c = _ET.SubElement(root, 'comment') c.text = comment for k, v in self._data.items(): entry = _ET.SubElement(root, 'entry') entry.set('key', str(k)) entry.text = str(v) tree = _ET.ElementTree(root) tree.write(out_stream, xml_declaration=True, encoding='UTF-8') def get(self, key): val = self._data.get(key) if val is not None: return val return self._defaults.get(key) if self._defaults else None def put(self, key, value): return super().put(str(key), str(value)) def toString(self) -> str: items = ", ".join(f"{k}={v}" for k, v in self._data.items()) return f"{{{items}}}" # ============================================================ # EnumSet # ============================================================ class EnumSet(HashSet): """java.util.EnumSet — simple implementation using set""" def __init__(self, c=None): super().__init__() self._element_type = None if c is not None: if isinstance(c, EnumSet): self._data = set(c._data) self._element_type = c._element_type elif isinstance(c, type): self._element_type = c elif isinstance(c, _IterableABC): for item in c: self._data.add(item) if self._element_type is None: self._element_type = item.__class__ @staticmethod def allOf(element_type) -> 'EnumSet': es = EnumSet() es._element_type = element_type if hasattr(element_type, '_values'): for v in element_type._values(): es._data.add(v) elif hasattr(element_type, '__members__'): for name, member in element_type.__members__.items(): es._data.add(member) return es @staticmethod def noneOf(element_type) -> 'EnumSet': es = EnumSet() es._element_type = element_type return es @staticmethod def range(element_type, from_val, to_val) -> 'EnumSet': es = EnumSet() es._element_type = element_type started = False if hasattr(element_type, '_values'): for v in element_type._values(): if v == from_val: started = True if started: es._data.add(v) if v == to_val: break elif hasattr(element_type, '__members__'): for name, member in element_type.__members__.items(): if member == from_val: started = True if started: es._data.add(member) if member == to_val: break return es @staticmethod def copyOf(es) -> 'EnumSet': return EnumSet(es) def complementOf(self, other: 'EnumSet') -> 'EnumSet': result = EnumSet.noneOf(self._element_type) if self._element_type and hasattr(self._element_type, '_values'): for v in self._element_type._values(): if v not in other._data: result._data.add(v) return result # ============================================================ # EnumMap # ============================================================ class EnumMap(HashMap): """java.util.EnumMap — simple implementation using dict""" def __init__(self, key_type=None, m=None): super().__init__() self._key_type = key_type if m is not None: if isinstance(m, EnumMap): self._data.update(m._data) self._key_type = m._key_type elif isinstance(m, dict): self._data.update(m) else: for k, v in m.items(): self._data[k] = v def put(self, key, value): if self._key_type is None: self._key_type = key.__class__ return super().put(key, value) def keySet(self): return set(self._data.keys()) # ============================================================ # Objects # ============================================================ class Objects: """java.util.Objects — static helper methods""" @staticmethod def equals(a, b) -> bool: return a == b @staticmethod def deepEquals(a, b) -> bool: return _deep_eq(a, b) @staticmethod def hashCode(o) -> int: return 0 if o is None else (hash(o) & 0x7FFFFFFF) @staticmethod def hash(*values) -> int: return Arrays.hashCode(values) @staticmethod def toString(o, null_default: str = "null") -> str: if o is None: return null_default return str(o) @staticmethod def compare(a, b, cmp) -> int: if cmp: return cmp(a, b) return (a > b) - (a < b) @staticmethod def requireNonNull(obj, message: Any = None): if obj is None: if message is None: raise TypeError("null") raise TypeError(str(message) if not callable(message) else message.get()) return obj @staticmethod def nonNull(obj) -> bool: return obj is not None @staticmethod def isNull(obj) -> bool: return obj is None @staticmethod def requireNonNullElse(obj, default): return obj if obj is not None else default @staticmethod def requireNonNullElseGet(obj, supplier): return obj if obj is not None else supplier() @staticmethod def checkIndex(index: int, length: int) -> int: if index < 0 or index >= length: raise IndexError(f"Index {index} out of bounds [0, {length})") return index @staticmethod def checkFromToIndex(from_index: int, to_index: int, length: int) -> int: if from_index < 0 or from_index > to_index or to_index > length: raise IndexError(f"Range [{from_index}, {to_index}) out of bounds [0, {length})") return from_index @staticmethod def checkFromIndexSize(from_index: int, size: int, length: int) -> int: if from_index < 0 or size < 0 or from_index + size > length: raise IndexError(f"Range [{from_index}, {from_index + size}) out of bounds [0, {length})") return from_index # ============================================================ # Locale # ============================================================ class Locale(Stub): """java.util.Locale — basic locale representation""" ENGLISH = None FRENCH = None GERMAN = None ITALIAN = None JAPANESE = None KOREAN = None CHINESE = None SIMPLIFIED_CHINESE = None TRADITIONAL_CHINESE = None FRANCE = None GERMANY = None ITALY = None JAPAN = None KOREA = None CHINA = None UK = None US = None CANADA = None CANADA_FRENCH = None ROOT = None def __init__(self, language: str = "", country: str = "", variant: str = ""): super().__init__() self._language = language self._country = country self._variant = variant @staticmethod def getDefault() -> 'Locale': return Locale("en", "US") @staticmethod def setDefault(locale: 'Locale') -> None: pass def getLanguage(self) -> str: return self._language def getCountry(self) -> str: return self._country def getVariant(self) -> str: return self._variant def getDisplayLanguage(self, locale: 'Locale' = None) -> str: return self._language def getDisplayCountry(self, locale: 'Locale' = None) -> str: return self._country def getDisplayName(self, locale: 'Locale' = None) -> str: parts = [self._language] if self._country: parts.append(self._country) if self._variant: parts.append(self._variant) return "_".join(parts) def toString(self) -> str: return self.getDisplayName() def toLanguageTag(self) -> str: tag = self._language if self._country: tag += "-" + self._country if self._variant: tag += "-" + self._variant return tag @staticmethod def forLanguageTag(tag: str) -> 'Locale': parts = tag.replace("-", "_").split("_") lang = parts[0] if len(parts) > 0 else "" country = parts[1] if len(parts) > 1 else "" variant = parts[2] if len(parts) > 2 else "" return Locale(lang, country, variant) def equals(self, other) -> bool: if isinstance(other, Locale): return (self._language == other._language and self._country == other._country and self._variant == other._variant) return False def hashCode(self) -> int: return hash((self._language, self._country, self._variant)) & 0x7FFFFFFF # Initialize Locale constants Locale.ENGLISH = Locale("en") Locale.FRENCH = Locale("fr") Locale.GERMAN = Locale("de") Locale.ITALIAN = Locale("it") Locale.JAPANESE = Locale("ja") Locale.KOREAN = Locale("ko") Locale.CHINESE = Locale("zh") Locale.SIMPLIFIED_CHINESE = Locale("zh", "CN") Locale.TRADITIONAL_CHINESE = Locale("zh", "TW") Locale.FRANCE = Locale("fr", "FR") Locale.GERMANY = Locale("de", "DE") Locale.ITALY = Locale("it", "IT") Locale.JAPAN = Locale("ja", "JP") Locale.KOREA = Locale("ko", "KR") Locale.CHINA = Locale("zh", "CN") Locale.UK = Locale("en", "GB") Locale.US = Locale("en", "US") Locale.CANADA = Locale("en", "CA") Locale.CANADA_FRENCH = Locale("fr", "CA") Locale.ROOT = Locale("", "") # ============================================================ # BitSet # ============================================================ class BitSet(Stub): """java.util.BitSet — bit manipulation""" def __init__(self, nbits: int = 0): super().__init__() if isinstance(nbits, int): self._bits = 0 elif isinstance(nbits, BitSet): self._bits = nbits._bits else: self._bits = 0 def _check(self, bit_index: int) -> None: if bit_index < 0: raise IndexError(f"bitIndex < 0: {bit_index}") def get(self, bit_index: int) -> bool: self._check(bit_index) return bool((self._bits >> bit_index) & 1) def getRange(self, from_index: int, to_index: int) -> 'BitSet': self._check(from_index) mask = ((1 << (to_index - from_index)) - 1) << from_index result = BitSet() result._bits = (self._bits & mask) >> from_index return result def set(self, bit_index: int, value: bool = True) -> None: self._check(bit_index) if value: self._bits |= (1 << bit_index) else: self._bits &= ~(1 << bit_index) def setRange(self, from_index: int, to_index: int, value: bool = True) -> None: self._check(from_index) mask = ((1 << (to_index - from_index)) - 1) << from_index if value: self._bits |= mask else: self._bits &= ~mask def clear(self, bit_index: int = None) -> None: if bit_index is None: self._bits = 0 else: self._check(bit_index) self._bits &= ~(1 << bit_index) def clearRange(self, from_index: int, to_index: int) -> None: self.setRange(from_index, to_index, False) def flip(self, bit_index: int) -> None: self._check(bit_index) self._bits ^= (1 << bit_index) def flipRange(self, from_index: int, to_index: int) -> None: self._check(from_index) mask = ((1 << (to_index - from_index)) - 1) << from_index self._bits ^= mask def cardinality(self) -> int: return self._bits.bit_count() def intersects(self, bs: 'BitSet') -> bool: return (self._bits & bs._bits) != 0 def and_(self, bs: 'BitSet') -> None: self._bits &= bs._bits def or_(self, bs: 'BitSet') -> None: self._bits |= bs._bits def xor(self, bs: 'BitSet') -> None: self._bits ^= bs._bits def andNot(self, bs: 'BitSet') -> None: self._bits &= ~bs._bits def size(self) -> int: return self._bits.bit_length() + (8 - (self._bits.bit_length() % 8)) % 8 def length(self) -> int: return self._bits.bit_length() def isEmpty(self) -> bool: return self._bits == 0 def nextSetBit(self, from_index: int) -> int: self._check(from_index) bits = self._bits >> from_index if bits == 0: return -1 return (bits & -bits).bit_length() - 1 + from_index def nextClearBit(self, from_index: int) -> int: self._check(from_index) bits = ~(self._bits >> from_index) if bits == 0: return -1 return (bits & -bits).bit_length() - 1 + from_index def previousSetBit(self, from_index: int) -> int: if from_index < 0: return -1 mask = (1 << (from_index + 1)) - 1 bits = self._bits & mask if bits == 0: return -1 return bits.bit_length() - 1 def previousClearBit(self, from_index: int) -> int: if from_index < 0: return -1 mask = (1 << (from_index + 1)) - 1 bits = (~self._bits) & mask if bits == 0: return -1 return bits.bit_length() - 1 def toByteArray(self) -> bytearray: if self._bits == 0: return bytearray() n_bytes = (self._bits.bit_length() + 7) // 8 return bytearray(self._bits.to_bytes(n_bytes, 'little')) def toLongArray(self) -> list: if self._bits == 0: return [] n_longs = (self._bits.bit_length() + 63) // 64 result = [] for i in range(n_longs): result.append((self._bits >> (i * 64)) & 0xFFFFFFFFFFFFFFFF) return result @staticmethod def valueOf(bytes_or_longs) -> 'BitSet': bs = BitSet() if isinstance(bytes_or_longs, (bytes, bytearray)): bs._bits = int.from_bytes(bytes_or_longs, 'little') elif isinstance(bytes_or_longs, list): for i, v in enumerate(bytes_or_longs): bs._bits |= (v & 0xFFFFFFFFFFFFFFFF) << (i * 64) return bs def stream(self): bits = [] i = 0 while True: idx = self.nextSetBit(i) if idx < 0: break bits.append(idx) i = idx + 1 return bits def equals(self, other) -> bool: if isinstance(other, BitSet): return self._bits == other._bits return False def hashCode(self) -> int: return hash(self._bits) & 0x7FFFFFFF def toString(self) -> str: bits = [] i = 0 while True: idx = self.nextSetBit(i) if idx < 0: break bits.append(str(idx)) i = idx + 1 return "{" + ", ".join(bits) + "}" def clone(self) -> 'BitSet': return BitSet(self) def __repr__(self): return self.toString() def __eq__(self, other): return self.equals(other) # ============================================================ # PriorityQueue # ============================================================ class PriorityQueue(Stub): """java.util.PriorityQueue — using heapq""" def __init__(self, initial_capacity: Any = None, comparator=None): super().__init__() self._heap: list = [] self._comparator = comparator if initial_capacity is not None and not isinstance(initial_capacity, (int, float)): if isinstance(initial_capacity, _IterableABC): for item in initial_capacity: self._heap.append(item) if comparator: self._heap.sort(key=comparator) else: self._heap.sort() def _wrap_key(self, obj): if self._comparator: return (self._comparator(obj), obj) return obj def add(self, obj) -> bool: _heapq.heappush(self._heap, self._wrap_key(obj)) return True def offer(self, obj) -> bool: return self.add(obj) def peek(self): return self._heap[0][1] if self._heap and self._comparator else (self._heap[0] if self._heap else None) def element(self): val = self.peek() if val is None: raise NoSuchElementException() return val def poll(self): if not self._heap: return None val = _heapq.heappop(self._heap) return val[1] if self._comparator else val def remove(self, obj) -> bool: if self._comparator: wrapped = self._wrap_key(obj) for i, v in enumerate(self._heap): if v == wrapped: self._heap[i] = self._heap[-1] self._heap.pop() _heapq.heapify(self._heap) return True else: for i, v in enumerate(self._heap): if v == obj: self._heap[i] = self._heap[-1] self._heap.pop() _heapq.heapify(self._heap) return True return False def size(self) -> int: return len(self._heap) def isEmpty(self) -> bool: return len(self._heap) == 0 def clear(self) -> None: self._heap.clear() def comparator(self): return self._comparator def iterator(self) -> Iterator: return Iterator(list(self._heap)) def toArray(self, a=None): if self._comparator: items = sorted([v[1] for v in self._heap], key=self._comparator) else: items = sorted(self._heap) if a is None: return items return items[:len(a)] def forEach(self, action) -> None: for item in list(self._heap): action(item) def toString(self) -> str: items = ", ".join(str(x) for x in self._heap) return f"[{items}]" def __len__(self): return len(self._heap) def __repr__(self): return self.toString() # ============================================================ # Vector # ============================================================ class Vector(Stub): """java.util.Vector — synchronized list""" def __init__(self, initial_capacity: Any = None, capacity_increment: int = 0): super().__init__() if initial_capacity is None: self._data = [] elif isinstance(initial_capacity, int): self._data = [] elif isinstance(initial_capacity, _IterableABC): self._data = list(initial_capacity) else: self._data = [] self._capacity_increment = capacity_increment self._lock = _threading.Lock() def _synchronized(self, func, *args, **kwargs): with self._lock: return func(*args, **kwargs) def add(self, obj) -> bool: with self._lock: self._data.append(obj) return True def addAt(self, index: int, obj) -> None: with self._lock: self._data.insert(index, obj) def addAll(self, c) -> bool: with self._lock: if isinstance(c, Vector): self._data.extend(c._data) else: self._data.extend(c) return True def addAllAt(self, index: int, c) -> bool: with self._lock: if isinstance(c, Vector): self._data[index:index] = c._data else: self._data[index:index] = list(c) return True def addElement(self, obj) -> None: self.add(obj) def capacity(self) -> int: with self._lock: return len(self._data) def clear(self) -> None: with self._lock: self._data.clear() def clone(self) -> 'Vector': with self._lock: return Vector(self._data) def contains(self, obj) -> bool: with self._lock: return obj in self._data def containsAll(self, c) -> bool: with self._lock: if isinstance(c, Vector): return all(x in self._data for x in c._data) return all(x in self._data for x in c) def copyInto(self, an_array: list) -> None: with self._lock: for i, v in enumerate(self._data): an_array[i] = v def elementAt(self, index: int): with self._lock: return self._data[index] def elements(self) -> Enumeration: with self._lock: return Enumeration(list(self._data)) def ensureCapacity(self, min_capacity: int) -> None: pass def firstElement(self): with self._lock: if not self._data: raise NoSuchElementException() return self._data[0] def forEach(self, action) -> None: with self._lock: for item in list(self._data): action(item) def get(self, index: int): with self._lock: return self._data[index] def indexOf(self, obj, index: int = 0) -> int: with self._lock: try: return self._data.index(obj, index) except ValueError: return -1 def insertElementAt(self, obj, index: int) -> None: with self._lock: self._data.insert(index, obj) def isEmpty(self) -> bool: with self._lock: return len(self._data) == 0 def iterator(self) -> Iterator: with self._lock: return Iterator(list(self._data)) def lastElement(self): with self._lock: if not self._data: raise NoSuchElementException() return self._data[-1] def lastIndexOf(self, obj, index: int = None) -> int: with self._lock: if index is None: index = len(self._data) - 1 for i in range(index, -1, -1): if self._data[i] == obj: return i return -1 def listIterator(self, index: int = 0) -> ListIterator: with self._lock: li = ListIterator(list(self._data)) li._index = index return li def remove(self, obj) -> bool: with self._lock: if obj in self._data: self._data.remove(obj) return True return False def removeAt(self, index: int): with self._lock: return self._data.pop(index) def removeAll(self, c) -> bool: with self._lock: if isinstance(c, Vector): items = c._data else: items = list(c) old_len = len(self._data) self._data = [x for x in self._data if x not in items] return len(self._data) != old_len def removeAllElements(self) -> None: with self._lock: self._data.clear() def removeElement(self, obj) -> bool: return self.remove(obj) def removeElementAt(self, index: int) -> None: with self._lock: self._data.pop(index) def removeIf(self, predicate) -> bool: with self._lock: old_len = len(self._data) self._data = [x for x in self._data if not predicate(x)] return len(self._data) != old_len def replaceAll(self, operator) -> None: with self._lock: self._data = [operator(x) for x in self._data] def retainAll(self, c) -> bool: with self._lock: if isinstance(c, Vector): items = set(c._data) else: items = set(c) old_len = len(self._data) self._data = [x for x in self._data if x in items] return len(self._data) != old_len def set(self, index: int, obj): with self._lock: old = self._data[index] self._data[index] = obj return old def setElementAt(self, obj, index: int) -> None: with self._lock: self._data[index] = obj def setSize(self, new_size: int) -> None: with self._lock: while len(self._data) < new_size: self._data.append(None) while len(self._data) > new_size: self._data.pop() def size(self) -> int: with self._lock: return len(self._data) def sort(self, key=None, reverse: bool = False) -> None: with self._lock: self._data.sort(key=key, reverse=reverse) def subList(self, from_index: int, to_index: int) -> 'Vector': with self._lock: return Vector(self._data[from_index:to_index]) def toArray(self, a=None): with self._lock: if a is None: return list(self._data) if len(a) < len(self._data): return list(self._data) for i, v in enumerate(self._data): a[i] = v if len(self._data) < len(a): a[len(self._data)] = None return a def toString(self) -> str: with self._lock: items = ", ".join(str(x) for x in self._data) return f"[{items}]" def trimToSize(self) -> None: pass def __len__(self): with self._lock: return len(self._data) def __getitem__(self, idx): with self._lock: return self._data[idx] def __setitem__(self, idx, val): with self._lock: self._data[idx] = val def __delitem__(self, idx): with self._lock: del self._data[idx] def __iter__(self): with self._lock: return iter(list(self._data)) def __repr__(self): return self.toString() def __contains__(self, obj): with self._lock: return obj in self._data def __eq__(self, other): if isinstance(other, Vector): with self._lock: return self._data == other._data return False # ============================================================ # Stack # ============================================================ class Stack(Vector): """java.util.Stack — extends Vector""" def __init__(self): super().__init__() def push(self, item): with self._lock: self._data.append(item) return item def pop(self): with self._lock: if not self._data: raise EmptyStackException() return self._data.pop() def peek(self): with self._lock: if not self._data: raise EmptyStackException() return self._data[-1] def empty(self) -> bool: with self._lock: return len(self._data) == 0 def search(self, obj) -> int: with self._lock: try: idx = len(self._data) - 1 - self._data[::-1].index(obj) return len(self._data) - idx except ValueError: return -1 def add(self, obj) -> bool: self.push(obj) return True def remove(self, obj) -> bool: with self._lock: if obj in self._data: self._data.remove(obj) return True return False