Skip to content

Instantly share code, notes, and snippets.

@ezhov-da
Last active March 10, 2019 12:23
Show Gist options
  • Save ezhov-da/6a919ff6dc49676a753ebe823fffaedf to your computer and use it in GitHub Desktop.
Save ezhov-da/6a919ff6dc49676a753ebe823fffaedf to your computer and use it in GitHub Desktop.
java cross join list
<p>Бывает так, что необходимо сделать cross join данных из List<T>, основываясь на подсказке со <a href="http://stackoverflow.com/questions/38568550/cross-join-two-lists-java">stackoverflow</a>, специально для такого случая я написал пару классов:</p>
[code:]LANG[:code]import java.lang.reflect.Array;
import java.util.List;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.stream.Collectors;
/**
* Делаем cross join списков
* <p>
* @author ezhov_da
*/
public class CrossJoinList<T>
{
private static final Logger LOG = Logger.getLogger(CrossJoinList.class.getName());
private static CrossJoinList listCrossJoin;
public static CrossJoinList getInstance()
{
if (Objects.isNull(listCrossJoin))
{
listCrossJoin = new CrossJoinList();
}
return listCrossJoin;
}
public List<ObjectCrossJoin<T>> crossJoinTwoList(Class<T> clazz, List<T> listOne, List<T> listTwo)
{
return listOne
.stream()
.flatMap(t
-> listTwo
.stream()
.map(t1 ->
{
T[] array = (T[]) Array.newInstance(clazz, 2);
array[0] = t;
array[1] = t1;
return new ObjectCrossJoin<T>(array);
}
)
).collect(Collectors.toList());
}
List<ObjectCrossJoin<T>> objectCrossJoins;
public synchronized List<ObjectCrossJoin<T>> executeCrossJoin(Class<T> clazz, List<T>... listsForJoin)
{
switch (listsForJoin.length)
{
case 0:
case 1:
throw new IllegalArgumentException("Not use for join one list. Min two list.");
case 2:
return crossJoinTwoList(clazz, listsForJoin[0], listsForJoin[1]);
default:
//сделано для того, чтоб cross join проводился в последовательности следования массива
List<T> listOne = listsForJoin[listsForJoin.length - 2];
List<T> listTwo = listsForJoin[listsForJoin.length - 1];
objectCrossJoins = crossJoinTwoList(clazz, listOne, listTwo);
for (int i = listsForJoin.length - 3; i >= 0; i--)
{
objectCrossJoins = listsForJoin[i]
.stream()
.flatMap(t
-> objectCrossJoins
.stream()
.map((ObjectCrossJoin<T> t1) ->
{
T[] array = t1.getArrayCrossJoin();
final T[] arrayResult = (T[]) Array.newInstance(clazz, array.length + 1);
arrayResult[0] = t;
for (int i1 = 1; i1 < arrayResult.length; i1++)
{
arrayResult[i1] = array[i1 - 1];
}
ObjectCrossJoin<T> objectCrossJoin = new ObjectCrossJoin<>(arrayResult);
return objectCrossJoin;
})
).collect(Collectors.toList());
}
return objectCrossJoins;
}
}
}
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Объект для замножения
* <p>
* @author ezhov_da
*/
public class ObjectCrossJoin<T>
{
private static final Logger LOG = Logger.getLogger(ObjectCrossJoin.class.getName());
private T[] arrayCrossJoin;
public ObjectCrossJoin(T... arrayCrossJoin)
{
this.arrayCrossJoin = arrayCrossJoin;
}
public T[] getArrayCrossJoin()
{
return arrayCrossJoin;
}
@Override
public String toString()
{
return Stream.of(arrayCrossJoin).map(t -> t.toString()).collect(Collectors.joining(","));
}
}
[/code]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment