Home

Awesome

Solid

Android Arsenal Maven Central Build Status

Solid is an Android library for data handling.

It provides:

Philosophy

Solid library adheres to the philosophy: "transform it as a stream, keep it as immutable". Thus allowing to pass collections around without a fear that they can be changed by another part of the application, while keeping the ability to transform data in a convenient way.

Include

dependencies {
    def solidVersion = '2.0.3'
    compile "info.android15.solid:streams:$solidVersion"
    compile "info.android15.solid:collections:$solidVersion"
}

Latest version: Maven Central

Lightweight data streams

Solid streams are similar to Java 8 streams but they are released under the MIT license and are absolutely free.

These streams are passive and do not emit items, they are not thread-safe, so they are much simpler.

All Solid streams are sequential.

How to use

All examples here with Java 8 syntax on. I recommend using Gradle Retrolambda Plugin to make your code shorter.

You can take any Iterable or an array and turn it into a set of chained methods:

stream(asList(1, 3, 2))                // Iterable<Integer>
    .filter(it -> it < 3)              // only 1 and 2 items are not filtered
    .map(it -> Integer.toString(it))   // convert Integer values to String values
    .collect(toList());

This code will result in a List<String> which contains "1" and "2" values.

Another example: we need to sort some items by name and then return their ids in a SolidList.

stream(namedEntities)
    .sort((left, right) -> left.name.compareTo(right.name))
    .map(it -> it.id)
    .collect(toSolidList());

Easy, isn't it? I believe you already know about the power of streaming operators, so here is a very lightweight and convenient implementation, especially for needs of an Android developer.

For a list of stream operators see: Solid streams by example

Data converters and primitive arrays

Here is how converters look like:

int[] values = of(1, 2, 3)  // Iterable<Integer> at this point
    .collect(toInts())      // int[]

Currently Solid supports conversion of these primitive types: byte, double, float, int, long.

You can write your own converters if you wish - just implement a converting function and pass it into Stream.collect().

Solid converters are quite powerful:

To convert a primitive array into an iterable stream just call one method. Call two methods to convert them into an immutable parcelable list.

SolidList<Byte> list = box(new byte[]{1, 2, 3})
    .collect(toSolidList());

Easy.

Want to join two primitive arrays?

byte[] joined = box(new byte[]{1, 2, 3})
    .merge(box(new byte[]{4, 5, 6}))
    .collect(toBytes());

Remove a value from a primitive array?

byte[] array_1_3 = box(new byte[]{1, 2, 3})
    .separate((byte) 2)
    .collect(toBytes());

And so on. The amount of flexibility that iterable streams and converters provide is hard to get at the beginning but as long as you use them, more and more ideas come into mind.

The full list of possible primitive converters is here: ToArrays, Primitives

Solid collections

If you're a big fan of immutable data structures like me then you also probably miss Parcelable interface implementation in Guava's immutable collections.

If you're not a big fan of immutability then you should be.

I recommend reading this library description to get started with immutability: AutoValue. The library has a very good Android port with Parcelable implementation: AutoParcel.

There is yet another library that makes a good combo with SolidList - Icepick. Solid collections can be safely passed between activities, services, intents and threads, and they can be automatically saved into an activity/fragment Bundle with just one annotation. Amazing.

Details

Solid collections are just a decorators around ArrayList, LinkedHashMap and LinkedHashSet, so I do not think that any docs are needed. UnsupportedOperationException will be thrown on each method that tries to modify a solid collection.

If you're familiar with Guava's immutable collections - there is a difference that is good to know. Solid collections do not have a support for Builder pattern - use ArrayList, Stream, Map and Set to prepare them.

Note that SolidMap is not java.util.Collection due to Android Parcelable Map issue (Map can not implement Parcelable).