All Downloads are FREE. Search and download functionalities are using the official Maven repository.

functionalj.tuple.Tuple2 Maven / Gradle / Ivy

There is a newer version: 1.0.17
Show newest version
// ============================================================================
// Copyright (c) 2017-2019 Nawapunth Manusitthipol (NawaMan - http://nawaman.net).
// ----------------------------------------------------------------------------
// MIT License
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// ============================================================================
package functionalj.tuple;

import static functionalj.function.Func.it;

import java.lang.reflect.Array;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;

import functionalj.function.Absent;
import functionalj.function.Func1;
import functionalj.function.Func2;
import functionalj.list.FuncList;
import functionalj.map.FuncMap;
import functionalj.map.ImmutableMap;
import functionalj.pipeable.Pipeable;
import lombok.val;

@SuppressWarnings("javadoc")
public interface Tuple2 extends Pipeable> {
    
    public static  Tuple2 of(Map.Entry entry) {
        return (entry == null)
                ? new ImmutableTuple2<>(null, null)
                : new ImmutableTuple2<>(entry);
    }
    public static  Tuple2 of(T1 t1, T2 t2) {
        return new ImmutableTuple2<>(t1, t2);
    }
    
    public T1 _1();
    public T2 _2();
    
    @Override
    public default Tuple2 __data() {
        return this;
    }
    
    public default Tuple2 swap() {
        return Tuple.of(_2(), _1());
    }
    
    public default ImmutableTuple2 toImmutableTuple() {
        return ImmutableTuple.of(this);
    }
    
    public default T1 first() {
        return _1();
    }
    
    public default T2 second() {
        return _2();
    }
    
    public default  Tuple3 with(T3 new3) {
        return new Tuple3() {
            @Override public T1 _1() { return Tuple2.this._1(); }
            @Override public T2 _2() { return Tuple2.this._2(); }
            @Override public T3 _3() { return new3; }
        };
    }
    
    public default Tuple2 with1(T1 new1) {
        return new Tuple2() {
            @Override public T1 _1() { return new1; }
            @Override public T2 _2() { return Tuple2.this._2(); }
        };
    }
    
    public default Tuple2 with1(Supplier supplier1) {
        return new Tuple2() {
            @Override public T1 _1() { return supplier1.get(); }
            @Override public T2 _2() { return Tuple2.this._2(); }
        };
    }
    
    public default Tuple2 with1(Func1 function1) {
        return new Tuple2() {
            @Override public T1 _1() { return function1.apply(Tuple2.this._1()); }
            @Override public T2 _2() { return Tuple2.this._2(); }
        };
    }
    
    public default Tuple2 with2(T2 new2) {
        return new Tuple2() {
            @Override public T1 _1() { return Tuple2.this._1(); }
            @Override public T2 _2() { return new2; }
        };
    }
    
    public default Tuple2 with2(Supplier supplier2) {
        return new Tuple2() {
            @Override public T1 _1() { return Tuple2.this._1(); }
            @Override public T2 _2() { return supplier2.get(); }
        };
    }
    
    public default Tuple2 with2(Func1 function2) {
        return new Tuple2() {
            @Override public T1 _1() { return Tuple2.this._1(); }
            @Override public T2 _2() { return function2.apply(Tuple2.this._2()); }
        };
    }
    
    public default Tuple2 withFirst(T1 new1) {
        return with1(new1);
    }
    
    public default Tuple2 withFirst(Supplier supplier1) {
        return with1(supplier1);
    }
    
    public default Tuple2 withFirst(Func1 function1) {
        return with1(function1);
    }
    
    public default Tuple2 withSecond(T2 new2) {
        return with2(new2);
    }
    
    public default Tuple2 withSecond(Supplier supplier2) {
        return with2(supplier2);
    }
    
    public default Tuple2 withSecond(Func1 function2) {
        return with2(function2);
    }
    
    public default Object[] toArray() {
        val _1 = _1();
        val _2 = _2();
        return new Object[] { _1, _2 };
    }
    
    public default  T[] toArray(Class type) {
        val _1 = _1();
        val _2 = _2();
        val array = Array.newInstance(type, 2);
        Array.set(array, 0, _1);
        Array.set(array, 1, _2);
        @SuppressWarnings("unchecked")
        val toArray = (T[])array;
        return toArray;
    }
    
    public default FuncList toList() {
        val _1 = _1();
        val _2 = _2();
        return FuncList.of(_1, _2);
    }
    
    public default  FuncMap toMap(K k1, K k2) {
        val e1 = (k1 != null) ? ImmutableTuple.of(k1, (Object)_1()) : null;
        val e2 = (k2 != null) ? ImmutableTuple.of(k2, (Object)_2()) : null;
        return ImmutableMap.ofEntries(e1, e2);
    }
    
    //== mapTo ==
    
    public default  T mapTo(BiFunction mapper) {
        val _1 = _1();
        val _2 = _2();
        return mapper.apply(_1, _2);
    }
    
    //== Map ==
    
    public default  Tuple2 map1(Function mapper) {
        return map(mapper, it());
    }
    
    public default  Tuple2 map2(Function mapper) {
        return map(it(), mapper);
    }
    
    public default  Tuple2 map(BiFunction> mapper) {
        val _1 = _1();
        val _2 = _2();
        return mapper.apply(_1, _2);
    }
    
    public default  Tuple2 map(
            Function mapper1,
            Function mapper2) {
        return map(mapper1, mapper2, Tuple::of);
    }
    public default  T map(
            Function mapper1, 
            Function mapper2, 
            BiFunction mapper) {
        val _1 = _1();
        val _2 = _2();
        val n1 = mapper1.apply(_1);
        val n2 = mapper2.apply(_2);
        return mapper.apply(n1, n2);
    }
    
    public default  Tuple2 map(Absent absent1, Function mapper2) {
        val _1 = _1();
        val _2 = _2();
        val n1 = _1;
        val n2 = mapper2.apply(_2);
        return Tuple.of(n1, n2);
    }
    
    public default  Tuple2 map(Function mapper1, Absent absent2) {
        val _1 = _1();
        val _2 = _2();
        val n1 = mapper1.apply(_1);
        val n2 = _2;
        return Tuple.of(n1, n2);
    }
    
    //== Reduce ==
    
    public default  TARGET reduce(Func2 reducer) {
        val _1     = _1();
        val _2     = _2();
        val target = reducer.apply(_1, _2);
        return target;
    }
    
    //== drop ==
    
    public default T1 drop() {
        val _1 = _1();
        return _1;
    }
    
}