Skip to content

Commit

Permalink
Added ConcurrentHashSet and CurrentHahsList, appropriate tests, and u…
Browse files Browse the repository at this point in the history
…pdate version to 2.7.0
  • Loading branch information
jdereg committed Apr 20, 2024
1 parent 6b33d32 commit 9467d14
Show file tree
Hide file tree
Showing 9 changed files with 721 additions and 30 deletions.
42 changes: 20 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,41 @@ java-util
[![Maven Central](https://badgen.net/maven/v/maven-central/com.cedarsoftware/java-util)](https://central.sonatype.com/search?q=java-util&namespace=com.cedarsoftware)
[![Javadoc](https://javadoc.io/badge/com.cedarsoftware/java-util.svg)](http://www.javadoc.io/doc/com.cedarsoftware/java-util)

Helpful utilities that are thoroughly tested (> 98% code coverage via JUnit tests).
Helpful utilities that are thoroughly tested.
Available on [Maven Central](https://central.sonatype.com/search?q=java-util&namespace=com.cedarsoftware).
This library has <b>no dependencies</b> on other libraries for runtime.
The`.jar`file is `250K.`
Works with`JDK 1.8`through`JDK 21`.
The`.jar`file is `260K` and works with`JDK 1.8`through`JDK 21`.
The '.jar' file classes are version 52 (`JDK 1.8`).
## Compatibility

### JPMS (Java Platform Module System)

This library is fully compatible with JPMS, commonly known as Java Modules. It includes a `module-info.class` file that
specifies module dependencies and exports.

### OSGi

This library also supports OSGi environments. It comes with pre-configured OSGi metadata in the `MANIFEST.MF` file, ensuring easy integration into any OSGi-based application.

Both of these features ensure that our library can be seamlessly integrated into modular Java applications, providing robust dependency management and encapsulation.

---
To include in your project:
##### Gradle
```
implementation 'com.cedarsoftware:java-util:2.6.0'
implementation 'com.cedarsoftware:java-util:2.7.0'
```

##### Maven
```
<dependency>
<groupId>com.cedarsoftware</groupId>
<artifactId>java-util</artifactId>
<version>2.6.0</version>
<version>2.7.0</version>
</dependency>
```
---

Since Java 1.5, you can statically import classes. Using this technique with many of the classes below, it makes their methods directly accessible in your source code, keeping your source code smaller and easier to read. For example:

```
import static com.cedarsoftware.util.Converter.*;
```
will permit you to write:
```
...
Calendar cal = convertToCalendar("2019/11/17");
Date date = convertToDate("November 17th, 2019 4:45pm");
TimeStamp stamp = convertToTimeStamp(cal);
AtomicLong atomicLong = convertToAtomicLong("123128300")
String s = convertToString(atomicLong)
...
```

Included in java-util:
* **ArrayUtilities** - Useful utilities for working with Java's arrays `[]`
* **ByteUtilities** - Useful routines for converting `byte[]` to HEX character `[]` and visa-versa.
Expand All @@ -55,7 +50,8 @@ same class.
* **CompactLinkedSet** - Small memory footprint `Set` that expands to a `LinkedHashSet` when `size() > compactSize()`.
* **CompactCILinkedSet** - Small memory footprint `Set` that expands to a case-insensitive `LinkedHashSet` when `size() > compactSize()`.
* **CompactCIHashSet** - Small memory footprint `Set` that expands to a case-insensitive `HashSet` when `size() > compactSize()`.
* **CaseInsensitiveSet** - `Set` that ignores case for `Strings` contained within.
* **CaseInsensitiveSet** - `Set` that ignores case for `Strings` contained within.
* **ConcurrentHashSet** - A thread-safe `Set` which does not require each element to be `Comparable` like `ConcurrentSkipListSet` which is a `NavigableSet,` which is a `SortedSet.`
* **Maps**
* **CompactMap** - Small memory footprint `Map` that expands to a `HashMap` when `size() > compactSize()` entries.
* **CompactLinkedMap** - Small memory footprint `Map` that expands to a `LinkedHashMap` when `size() > compactSize()` entries.
Expand All @@ -64,6 +60,8 @@ same class.
* **CaseInsensitiveMap** - `Map` that ignores case when `Strings` are used as keys.
* **LRUCache** - Thread safe LRUCache that implements the full Map API and supports a maximum capacity. Once max capacity is reached, placing another item in the cache will cause the eviction of the item that was the least recently used (LRU).
* **TrackingMap** - `Map` class that tracks when the keys are accessed via `.get()` or `.containsKey()`. Provided by @seankellner
* **Lists**
* **ConcurrentList** - Provides a thread-safe `List` with all API support except for `listIterator(),` however, it implements `iterator()` which returns an iterator to a snapshot copy of the `List.`
* **Converter** - Convert from one instance to another. For example, `convert("45.3", BigDecimal.class)` will convert the `String` to a `BigDecimal`. Works for all primitives, primitive wrappers, `Date`, `java.sql.Date`, `String`, `BigDecimal`, `BigInteger`, `AtomicBoolean`, `AtomicLong`, etc. The method is very generous on what it allows to be converted. For example, a `Calendar` instance can be input for a `Date` or `Long`. Call the method `Converter.getSupportedConversions()` or `Converter.allSupportedConversions()` to get a list of all source/target conversions. Currently, there are 680+ conversions.
* **DateUtilities** - Robust date String parser that handles date/time, date, time, time/date, string name months or numeric months, skips comma, etc. English month names only (plus common month name abbreviations), time with/without seconds or milliseconds, `y/m/d` and `m/d/y` ordering as well.
* **DeepEquals** - Compare two object graphs and return 'true' if they are equivalent, 'false' otherwise. This will handle cycles in the graph, and will call an `equals()` method on an object if it has one, otherwise it will do a field-by-field equivalency check for non-transient fields. Has options to turn on/off using `.equals()` methods that may exist on classes.
Expand Down
4 changes: 4 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
### Revision History
* 2.7.0
* Added `ConcurrentHashList,` which implements a thread-safe `List.` Provides all API support except for `listIterator(),` however, it implements `iterator()` which returns an iterator to a snapshot copy of the `List.`
* Added `ConcurrentHashSet,` a true `Set` which is a bit easier to use than `ConcurrentSkipListSet,` which as a `NaviableSet` and `SortedSet,` requires each element to be `Comparable.`
* Performance improvement: On `LRUCache,` removed unnecessary `Collections.SynchronizedMap` surrounding the internal `LinkedHashMap` as the concurrent protection offered by `ReentrantReadWriteLock` is all that is needed.
* 2.6.0
* Performance improvement: `Converter` instance creation is faster due to the code no longer copying the static default table. Overrides are kept in separate variable.
* New capability added: `MathUtilities.parseToMinimalNumericType()` which will parse a String number into a Long, BigInteger, Double, or BigDecimal, choosing the "smallest" datatype to represent the number without loss of precision.
Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<groupId>com.cedarsoftware</groupId>
<artifactId>java-util</artifactId>
<packaging>bundle</packaging>
<version>2.6.0</version>
<version>2.7.0</version>
<description>Java Utilities</description>
<url>https://github.com/jdereg/java-util</url>

Expand Down Expand Up @@ -37,12 +37,12 @@
<version.junit-jupiter-params>5.10.2</version.junit-jupiter-params>
<version.mockito-junit-jupiter>4.11.0</version.mockito-junit-jupiter>
<version.assertj-core>3.25.3</version.assertj-core>
<version.json-io>4.19.13</version.json-io>
<version.json-io>4.21.0</version.json-io>
<version.agrona>1.21.1</version.agrona>

<!-- Build maven-***-plugins -->
<version.maven-jar-plugin>3.3.0</version.maven-jar-plugin>
<version.maven-gpg-plugin>3.2.2</version.maven-gpg-plugin>
<version.maven-jar-plugin>3.4.1</version.maven-jar-plugin>
<version.maven-gpg-plugin>3.2.4</version.maven-gpg-plugin>
<version.maven-compiler-plugin>3.13.0</version.maven-compiler-plugin>
<version.maven-javadoc-plugin>3.6.3</version.maven-javadoc-plugin>
<version.maven-surefire-plugin>3.2.5</version.maven-surefire-plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class CaseInsensitiveSet<E> implements Set<E>

public CaseInsensitiveSet(Collection<? extends E> collection)
{
if (collection instanceof ConcurrentSkipListSet)
if (collection instanceof ConcurrentSkipListSet || collection instanceof ConcurrentHashSet)
{
map = new CaseInsensitiveMap<>(new ConcurrentSkipListMap<>());
}
Expand Down
79 changes: 79 additions & 0 deletions src/main/java/com/cedarsoftware/util/ConcurrentHashSet.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package com.cedarsoftware.util;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
* @author John DeRegnaucourt ([email protected])
* <br>
* Copyright (c) Cedar Software LLC
* <br><br>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <br><br>
* <a href="http://www.apache.org/licenses/LICENSE-2.0">License</a>
* <br><br>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class ConcurrentHashSet<T> implements Set<T> {
private final Set<T> set = ConcurrentHashMap.newKeySet();

public boolean add(T e) {
return set.add(e);
}

public boolean remove(Object o) {
return set.remove(o);
}

public boolean containsAll(Collection<?> c) {
return set.containsAll(c);
}

public boolean addAll(Collection<? extends T> c) {
return set.addAll(c);
}

public boolean retainAll(Collection<?> c) {
return set.retainAll(c);
}

public boolean removeAll(Collection<?> c) {
return set.removeAll(c);
}

public void clear() {
set.clear();
}

public boolean contains(Object o) {
return set.contains(o);
}

public boolean isEmpty() {
return set.isEmpty();
}

public Iterator<T> iterator() {
return set.iterator();
}

public int size() {
return set.size();
}

public Object[] toArray() {
return set.toArray();
}

public <T1> T1[] toArray(T1[] a) {
return set.toArray(a);
}
}
Loading

0 comments on commit 9467d14

Please sign in to comment.