This repository contains implementations of some commonly-used Java collections in JavaScript.
Although JavaScript has a native Map
object, key equality is determined by the sameValueZero
algorithm, so objects with the exact same properties are not considered equal unless they are the same reference ({a: 1, b: 2} !== {a: 1, b: 2}
). This cannot be customized.
HashMap.js provides fine-grained control over what objects are considered equal, so both primitives and user-defined objects may be used as keys.
It implements a Hash Table/Map with similar methods to Java's HashMap.
All objects (except primitives) used as keys must implement a hashCode
method to return an integer hash code as well as an equals
method that accepts another object as a parameter and returns whether or not the value of the current object is equal to parameter. Objects that are considered equal must have the same hash code, but the converse is not true.
Note that HashMap
instances are iterable, so [...myHashMap]
will return an array of arrays, where each inner array consists of the key and value for a mapping (in that order).
An example of usage can be found here.
Include the script before code that uses HashMap
. The script can be loaded via CDN or a local downloaded copy.
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<!-- old version -->
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/[email protected]/src/HashMap.js" integrity="sha384-AD+fe06BloScT8iK5vgKw2FW3imLYjVLP6P9OS+zKpI8vIaNrBTKnQ4TCa4poj2F" crossorigin="anonymous"></script>
Or for Node.js, run npm i java-collections4js
to install the package, then use it like so:
const { HashMap } = require("java-collections4js");
// or with ECMAScript Module imports
import JavaCollections from "java-collections4js"; // use JavaCollections.HashMap
import HashMap from "java-collections4js/dist/HashMap.js";
The constructor accepts an optional HashMap
, which will copy the contents. Alternately, it will create an empty HashMap
.
const myMap = new HashMap(); // create empty HashMap
const myMap2 = new HashMap(myMap); // create HashMap from other HashMap
Method Signature | Description |
---|---|
put(key, value) | Associates the given key with the value . Returns the previous value associated with the key, or undefined if there was no value before. |
putIfAbsent(key, value) | Associates the given key with the value only if there was no value previously associated with the key. |
get(key) | Returns the value associated with the given key or undefined if there was no value. |
getOrDefault(key, defaultValue) | Returns the value associated with the given key if there is one or defaultValue if not. |
containsKey(key) | Returns true if the HashMap contains a mapping for the given key . |
containsValue(value) | Returns true if there is at least one key mapped to the given value . |
clear() | Removes all mappings in the HashMap . |
remove(key) | Removes the mapping for the given key and returns its value. |
forEach(consumer) | Iterates over each key-value mapping in the HashMap and passes the key and value of each one as arguments to the consumer callback function. |
isEmpty() | Returns true if there are no mappings in the HashMap |
size() | Returns the number of mappings in the HashMap . |
hashCode() | Returns an integer hash code for this instance. |
equals(obj) | Returns true if the value of obj is equal to the value of this instance. |
Although JavaScript has a native Set
object, elements are considered equal only if they are primitives with the same value or the same reference of an object. Thus, objects with the same properties and values can be duplicated many times.
HashSet.js provides fine-grained control over what objects are considered equal, so both primitives and user-defined objects may be inserted with uniqueness guaranteed.
It implements an unordered collection with unique elements. Similar to HashMap
, each element (except primitives) stored in a HashSet
must implement a hashCode
and equals
method. To use HashSet
, HashMap
must be included first.
Note that HashSet
instances are iterable, so [...myHashSet]
will return an array containing the elements in the HashSet
.
Include HashMap.js and HashSet.js before code that uses HashSet
. The scripts can be loaded via CDN or local downloaded copies.
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/[email protected]/src/HashMap.js" integrity="sha384-AD+fe06BloScT8iK5vgKw2FW3imLYjVLP6P9OS+zKpI8vIaNrBTKnQ4TCa4poj2F" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/[email protected]/src/HashSet.js" integrity="sha384-eEGZyLlAVNsmA+/PWbSLgZR1wO9z2AWkHyVtLzr1vCenlCZ2wb9wLxNKY7Ib5lK5" crossorigin="anonymous"></script>
The constructor accepts an optional iterable object, all elements of which will be initially added to the HashSet
. If the first parameter is not provided, it constructs an empty HashSet
.
const mySet = new HashSet(); // creates empty HashSet
const mySet2 = new HashSet([1, 2, 3]); // creates a HashSet containing the elements of the array
Method Signature | Description |
---|---|
add(obj) | Adds obj to the HashSet , if it is not already present. Returns true if the object was added, i.e. it was not already present. |
contains(obj) |
Returns true if the HashSet contains obj . |
remove(obj) | Removes obj from the HashSet . |
clear() | Removes all elements from the HashSet . |
size() | Returns the number of elements in the HashSet . |
isEmpty() | Returns true if there are no elements in the HashSet |
hashCode() | Returns an integer hash code for this instance. |
equals(obj) | Returns true if the value of obj is equal to the value of this instance. |
ArrayList.js implements an dynamically-sized list with a hashCode
and equals
method.
Note that ArrayList
instances are iterable, so [...myArrayList]
will return an array containing the elements in the ArrayList
(in order).
Include the script before code that uses ArrayList
. The script can be loaded via CDN or a local downloaded copy.
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/[email protected]/src/ArrayList.js" integrity="sha384-Uz+oGp/Q3Lfeq6ESB4bvbOAHw0hF1RjSBPHQqjpikrVrFjF6SDx6JMV9rI3mBBFr" crossorigin="anonymous"></script>
The constructor accepts an optional iterable object to use to fill the list initially. If not specified, an empty ArrayList
is constructed.
const myList = new ArrayList(); // creates an empty ArrayList
const myList2 = new ArrayList([1, 2, 3]); // creates an ArrayList containing the numbers 1, 2, 3
Method Signature | Description |
---|---|
add(...elems) | Adds all of the arguments passed in to the ArrayList . |
addAll(obj) | Adds all the elements of the iterable obj to the ArrayList . |
removeAtIndex(idx) | Removes the element at the specified index. |
get(idx) | Returns the element at the specified index. |
addAtIndex(idx, ...elems) |
Adds the given elements to the ArrayList starting at the specified index. |
set(idx, elem) | Sets the element at the specified index to be elem . |
removeIf(predicate) |
Removes all elements in the ArrayList that match a predicate (that accepts an element as the only parameter and returns true if it should be removed). |
remove(obj) |
Removes the first occurrence of obj from the ArrayList . |
indexOf(obj) |
Returns the first index at which obj is found in the ArrayList . |
size() |
Returns the number of elements in the ArrayList . |
isEmpty() |
Returns true if there are no elements in the ArrayList . |
hashCode() | Returns an integer hash code for this instance. |
equals(obj) | Returns true if the value of obj is equal to the value of this instance. |
HashedObject.js provides a wrapper for an object that allows specifying an equals
and hashCode
function. This wrapped object can then be used as a key in a HashMap
or stored
in a HashSet
.
Include the script before code that uses HashedObject
. The script can be loaded via CDN or a local downloaded copy.
<script src="https://cdn.jsdelivr.net/gh/LieutenantPeacock/[email protected]/src/HashedObject.js" integrity="sha384-RBqyEB5bCB2ci4e3ZKiBp4W87K7LYay1qXMFO/9cUq7TndRlQKLSZ4/iFN1bMbRl" crossorigin="anonymous"></script>
The constructor takes the object to wrap, the hash function, and the equals function as arguments.
The equals
function must take two objects as parameters and return a boolean indicating whether they are equal. If not equals function is specified, the default is strict equality comparison.
The hashCode
function must take one object as input and return its hash code.
let wrapped = new HashedObject(myObj, hashFn, equalsFn);
Method Signature | Description |
---|---|
hashCode() | Returns the hash code of the wrapped object obtained with the hashCode function passed in through the constructor. |
equals(obj) | Returns the result of calling the equals function provided in the constructor, passing the underlying object and obj as arguments. |
getValue() | Returns the underlying object that was wrapped. |
There are some static methods and properties provided for convenience that implement common equals or hash code functions.
Name | Description |
---|---|
DEFAULT_EQUALS | A function implementing an equals function using strict equality. |
ITERABLE_HASHCODE | A function implementing a hash code function for an iterable object. |
STRING_HASHCODE | A function implementing a hash code function for a string. |
ITERABLE_EQUALS | A function implementing an equals function for iterable objects by comparing elements at corresponding indexes. |
factory(hashCodeFn, equalsFn) | Returns a factory function from the given hash code and equals functions. The factory function accepts a single object parameter and returns a HashedObject from the parameter and the hash code and equals functions (provided when creating the factory). |