Process N lists simultaneously by doing permutations
up vote
0
down vote
favorite
I'm trying to see if someone can come up with a better solution for this algorithm.
I have an input of three lists/queues and I have to group/sort the elements of xpn, tu, and efx — depending on the presence (or not) of UniqueKey. For instance, if UniqueKey exists, I have to try to form a list/tuple of xpn, tu, and efx (if they exists for that UniqueKey)...and so on.
This is the "main" class:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public final class Request {
private Map<String, List<Tuple3<Node, Node, Node>>> result;
private Queue<Node> xpn;
private Queue<Node> tu;
private Queue<Node> efx;
public Map<String, List<Tuple3<Node, Node, Node>>> transform() {
final int max = estimateSize();
result = new LinkedHashMap<>(max / 3);
for (int i = 0; i < max; i++) {
pollFrom(xpn).ifPresent(it -> process(it, Category.XPN));
pollFrom(tu).ifPresent(it -> process(it, Category.TU));
pollFrom(efx).ifPresent(it -> process(it, Category.EFX));
}
return Collections.unmodifiableMap(result);
}
private int estimateSize() {
final int sizes = { sizeOf(xpn), sizeOf(tu), sizeOf(efx) };
int max = sizes[0];
for (int i = 1; i < sizes.length; i++) {
if (sizes[i] > max) { max = sizes[i]; }
}
return max;
}
private Optional<Node> pollFrom(final Queue<Node> collection) {
return (null != collection) ? Optional.ofNullable(collection.poll()) : Optional.empty();
}
private void process(final Node thiz, final Category category) {
if (result.containsKey(thiz.getUniqueKey())) {
final List<Tuple3<Node, Node, Node>> values = result.get(thiz.getUniqueKey());
final Optional<Tuple3<Node, Node, Node>> optional = values.stream()
.filter(tuple3 -> emptyBucket.apply(tuple3, category))
.findFirst();
if (optional.isPresent()) {
final Tuple3<Node, Node, Node> tuple3 = optional.get();
if (Category.XPN == category) {
tuple3.update1(thiz);
} else if (Category.TU == category) {
tuple3.update2(thiz);
} else {
tuple3.update3(thiz);
}
} else {
result.get(thiz.getUniqueKey()).add(tupleFrom(thiz, category));
}
} else {
final List<Tuple3<Node, Node, Node>> list = new LinkedList<>();
list.add(tupleFrom(thiz, category));
result.put((null != thiz.getUniqueKey()) ? thiz.getUniqueKey() : IdGen.uuid(), list);
}
}
private BiFunction<Tuple3<Node, Node, Node>, Category, Boolean> emptyBucket = (tuple, category) -> {
if (Category.XPN == category) {
return null == tuple._1();
} else if (Category.TU == category) {
return null == tuple._2();
} else { // EFX
return null == tuple._3();
}
};
private Tuple3<Node, Node, Node> tupleFrom(final Node thiz, final Category category) {
final Tuple3<Node, Node, Node> empty = new Tuple3<>(null, null, null);
switch (category) {
case XPN:
return empty.update1(thiz);
case TU:
return empty.update2(thiz);
case EFX:
return empty.update3(thiz);
}
return empty;
}
private int sizeOf(final Collection<Node> collection) {
return (null != collection) ? collection.size() : 0;
}
private enum Category {
XPN, // 1st element in tuple
TU, // 2nd element in tuple
EFX // 3rd element in tuple
}
}
The content of Node and Tuple3 are irrelevant, but I can post it if that may help. I'm just trying to see if there is a better way of doing this. The reason you don't see a constructor is because that class is being constructed/deserialized via Jackson. I would really like to avoid having result at class level.
PS: Don't mind about the method/variable names.
java algorithm linked-list
bumped to the homepage by Community♦ 2 days ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
add a comment |
up vote
0
down vote
favorite
I'm trying to see if someone can come up with a better solution for this algorithm.
I have an input of three lists/queues and I have to group/sort the elements of xpn, tu, and efx — depending on the presence (or not) of UniqueKey. For instance, if UniqueKey exists, I have to try to form a list/tuple of xpn, tu, and efx (if they exists for that UniqueKey)...and so on.
This is the "main" class:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public final class Request {
private Map<String, List<Tuple3<Node, Node, Node>>> result;
private Queue<Node> xpn;
private Queue<Node> tu;
private Queue<Node> efx;
public Map<String, List<Tuple3<Node, Node, Node>>> transform() {
final int max = estimateSize();
result = new LinkedHashMap<>(max / 3);
for (int i = 0; i < max; i++) {
pollFrom(xpn).ifPresent(it -> process(it, Category.XPN));
pollFrom(tu).ifPresent(it -> process(it, Category.TU));
pollFrom(efx).ifPresent(it -> process(it, Category.EFX));
}
return Collections.unmodifiableMap(result);
}
private int estimateSize() {
final int sizes = { sizeOf(xpn), sizeOf(tu), sizeOf(efx) };
int max = sizes[0];
for (int i = 1; i < sizes.length; i++) {
if (sizes[i] > max) { max = sizes[i]; }
}
return max;
}
private Optional<Node> pollFrom(final Queue<Node> collection) {
return (null != collection) ? Optional.ofNullable(collection.poll()) : Optional.empty();
}
private void process(final Node thiz, final Category category) {
if (result.containsKey(thiz.getUniqueKey())) {
final List<Tuple3<Node, Node, Node>> values = result.get(thiz.getUniqueKey());
final Optional<Tuple3<Node, Node, Node>> optional = values.stream()
.filter(tuple3 -> emptyBucket.apply(tuple3, category))
.findFirst();
if (optional.isPresent()) {
final Tuple3<Node, Node, Node> tuple3 = optional.get();
if (Category.XPN == category) {
tuple3.update1(thiz);
} else if (Category.TU == category) {
tuple3.update2(thiz);
} else {
tuple3.update3(thiz);
}
} else {
result.get(thiz.getUniqueKey()).add(tupleFrom(thiz, category));
}
} else {
final List<Tuple3<Node, Node, Node>> list = new LinkedList<>();
list.add(tupleFrom(thiz, category));
result.put((null != thiz.getUniqueKey()) ? thiz.getUniqueKey() : IdGen.uuid(), list);
}
}
private BiFunction<Tuple3<Node, Node, Node>, Category, Boolean> emptyBucket = (tuple, category) -> {
if (Category.XPN == category) {
return null == tuple._1();
} else if (Category.TU == category) {
return null == tuple._2();
} else { // EFX
return null == tuple._3();
}
};
private Tuple3<Node, Node, Node> tupleFrom(final Node thiz, final Category category) {
final Tuple3<Node, Node, Node> empty = new Tuple3<>(null, null, null);
switch (category) {
case XPN:
return empty.update1(thiz);
case TU:
return empty.update2(thiz);
case EFX:
return empty.update3(thiz);
}
return empty;
}
private int sizeOf(final Collection<Node> collection) {
return (null != collection) ? collection.size() : 0;
}
private enum Category {
XPN, // 1st element in tuple
TU, // 2nd element in tuple
EFX // 3rd element in tuple
}
}
The content of Node and Tuple3 are irrelevant, but I can post it if that may help. I'm just trying to see if there is a better way of doing this. The reason you don't see a constructor is because that class is being constructed/deserialized via Jackson. I would really like to avoid having result at class level.
PS: Don't mind about the method/variable names.
java algorithm linked-list
bumped to the homepage by Community♦ 2 days ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
I don't think I understand your grouping. I can tell what your code is doing ... but why? If a node has a unique key, can you really have more than 1 of those keys? I would expect at most 1 tuple of nodes with the same key which would greatly simplify the code.
– Imus
Mar 19 at 9:36
A tuple can have, by unique key, one (two or three) element(s) ofXPN,TU, andEFX. You can have another tuple for the same unique key with (almost) the same elements. The data is like that, hence the use of aListand not aSet. For a given unique key, you need to figure it out how many elements ofXPN,TU, andEFX, filling up the tuples whenever you find one of those. You build a new tuple for the same unique key when you find two elements of, for instance,XPN,TU, orEFX...and so on.
– x80486
Mar 19 at 14:24
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I'm trying to see if someone can come up with a better solution for this algorithm.
I have an input of three lists/queues and I have to group/sort the elements of xpn, tu, and efx — depending on the presence (or not) of UniqueKey. For instance, if UniqueKey exists, I have to try to form a list/tuple of xpn, tu, and efx (if they exists for that UniqueKey)...and so on.
This is the "main" class:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public final class Request {
private Map<String, List<Tuple3<Node, Node, Node>>> result;
private Queue<Node> xpn;
private Queue<Node> tu;
private Queue<Node> efx;
public Map<String, List<Tuple3<Node, Node, Node>>> transform() {
final int max = estimateSize();
result = new LinkedHashMap<>(max / 3);
for (int i = 0; i < max; i++) {
pollFrom(xpn).ifPresent(it -> process(it, Category.XPN));
pollFrom(tu).ifPresent(it -> process(it, Category.TU));
pollFrom(efx).ifPresent(it -> process(it, Category.EFX));
}
return Collections.unmodifiableMap(result);
}
private int estimateSize() {
final int sizes = { sizeOf(xpn), sizeOf(tu), sizeOf(efx) };
int max = sizes[0];
for (int i = 1; i < sizes.length; i++) {
if (sizes[i] > max) { max = sizes[i]; }
}
return max;
}
private Optional<Node> pollFrom(final Queue<Node> collection) {
return (null != collection) ? Optional.ofNullable(collection.poll()) : Optional.empty();
}
private void process(final Node thiz, final Category category) {
if (result.containsKey(thiz.getUniqueKey())) {
final List<Tuple3<Node, Node, Node>> values = result.get(thiz.getUniqueKey());
final Optional<Tuple3<Node, Node, Node>> optional = values.stream()
.filter(tuple3 -> emptyBucket.apply(tuple3, category))
.findFirst();
if (optional.isPresent()) {
final Tuple3<Node, Node, Node> tuple3 = optional.get();
if (Category.XPN == category) {
tuple3.update1(thiz);
} else if (Category.TU == category) {
tuple3.update2(thiz);
} else {
tuple3.update3(thiz);
}
} else {
result.get(thiz.getUniqueKey()).add(tupleFrom(thiz, category));
}
} else {
final List<Tuple3<Node, Node, Node>> list = new LinkedList<>();
list.add(tupleFrom(thiz, category));
result.put((null != thiz.getUniqueKey()) ? thiz.getUniqueKey() : IdGen.uuid(), list);
}
}
private BiFunction<Tuple3<Node, Node, Node>, Category, Boolean> emptyBucket = (tuple, category) -> {
if (Category.XPN == category) {
return null == tuple._1();
} else if (Category.TU == category) {
return null == tuple._2();
} else { // EFX
return null == tuple._3();
}
};
private Tuple3<Node, Node, Node> tupleFrom(final Node thiz, final Category category) {
final Tuple3<Node, Node, Node> empty = new Tuple3<>(null, null, null);
switch (category) {
case XPN:
return empty.update1(thiz);
case TU:
return empty.update2(thiz);
case EFX:
return empty.update3(thiz);
}
return empty;
}
private int sizeOf(final Collection<Node> collection) {
return (null != collection) ? collection.size() : 0;
}
private enum Category {
XPN, // 1st element in tuple
TU, // 2nd element in tuple
EFX // 3rd element in tuple
}
}
The content of Node and Tuple3 are irrelevant, but I can post it if that may help. I'm just trying to see if there is a better way of doing this. The reason you don't see a constructor is because that class is being constructed/deserialized via Jackson. I would really like to avoid having result at class level.
PS: Don't mind about the method/variable names.
java algorithm linked-list
I'm trying to see if someone can come up with a better solution for this algorithm.
I have an input of three lists/queues and I have to group/sort the elements of xpn, tu, and efx — depending on the presence (or not) of UniqueKey. For instance, if UniqueKey exists, I have to try to form a list/tuple of xpn, tu, and efx (if they exists for that UniqueKey)...and so on.
This is the "main" class:
@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public final class Request {
private Map<String, List<Tuple3<Node, Node, Node>>> result;
private Queue<Node> xpn;
private Queue<Node> tu;
private Queue<Node> efx;
public Map<String, List<Tuple3<Node, Node, Node>>> transform() {
final int max = estimateSize();
result = new LinkedHashMap<>(max / 3);
for (int i = 0; i < max; i++) {
pollFrom(xpn).ifPresent(it -> process(it, Category.XPN));
pollFrom(tu).ifPresent(it -> process(it, Category.TU));
pollFrom(efx).ifPresent(it -> process(it, Category.EFX));
}
return Collections.unmodifiableMap(result);
}
private int estimateSize() {
final int sizes = { sizeOf(xpn), sizeOf(tu), sizeOf(efx) };
int max = sizes[0];
for (int i = 1; i < sizes.length; i++) {
if (sizes[i] > max) { max = sizes[i]; }
}
return max;
}
private Optional<Node> pollFrom(final Queue<Node> collection) {
return (null != collection) ? Optional.ofNullable(collection.poll()) : Optional.empty();
}
private void process(final Node thiz, final Category category) {
if (result.containsKey(thiz.getUniqueKey())) {
final List<Tuple3<Node, Node, Node>> values = result.get(thiz.getUniqueKey());
final Optional<Tuple3<Node, Node, Node>> optional = values.stream()
.filter(tuple3 -> emptyBucket.apply(tuple3, category))
.findFirst();
if (optional.isPresent()) {
final Tuple3<Node, Node, Node> tuple3 = optional.get();
if (Category.XPN == category) {
tuple3.update1(thiz);
} else if (Category.TU == category) {
tuple3.update2(thiz);
} else {
tuple3.update3(thiz);
}
} else {
result.get(thiz.getUniqueKey()).add(tupleFrom(thiz, category));
}
} else {
final List<Tuple3<Node, Node, Node>> list = new LinkedList<>();
list.add(tupleFrom(thiz, category));
result.put((null != thiz.getUniqueKey()) ? thiz.getUniqueKey() : IdGen.uuid(), list);
}
}
private BiFunction<Tuple3<Node, Node, Node>, Category, Boolean> emptyBucket = (tuple, category) -> {
if (Category.XPN == category) {
return null == tuple._1();
} else if (Category.TU == category) {
return null == tuple._2();
} else { // EFX
return null == tuple._3();
}
};
private Tuple3<Node, Node, Node> tupleFrom(final Node thiz, final Category category) {
final Tuple3<Node, Node, Node> empty = new Tuple3<>(null, null, null);
switch (category) {
case XPN:
return empty.update1(thiz);
case TU:
return empty.update2(thiz);
case EFX:
return empty.update3(thiz);
}
return empty;
}
private int sizeOf(final Collection<Node> collection) {
return (null != collection) ? collection.size() : 0;
}
private enum Category {
XPN, // 1st element in tuple
TU, // 2nd element in tuple
EFX // 3rd element in tuple
}
}
The content of Node and Tuple3 are irrelevant, but I can post it if that may help. I'm just trying to see if there is a better way of doing this. The reason you don't see a constructor is because that class is being constructed/deserialized via Jackson. I would really like to avoid having result at class level.
PS: Don't mind about the method/variable names.
java algorithm linked-list
java algorithm linked-list
asked Mar 5 at 3:44
x80486
1356
1356
bumped to the homepage by Community♦ 2 days ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
bumped to the homepage by Community♦ 2 days ago
This question has answers that may be good or bad; the system has marked it active so that they can be reviewed.
I don't think I understand your grouping. I can tell what your code is doing ... but why? If a node has a unique key, can you really have more than 1 of those keys? I would expect at most 1 tuple of nodes with the same key which would greatly simplify the code.
– Imus
Mar 19 at 9:36
A tuple can have, by unique key, one (two or three) element(s) ofXPN,TU, andEFX. You can have another tuple for the same unique key with (almost) the same elements. The data is like that, hence the use of aListand not aSet. For a given unique key, you need to figure it out how many elements ofXPN,TU, andEFX, filling up the tuples whenever you find one of those. You build a new tuple for the same unique key when you find two elements of, for instance,XPN,TU, orEFX...and so on.
– x80486
Mar 19 at 14:24
add a comment |
I don't think I understand your grouping. I can tell what your code is doing ... but why? If a node has a unique key, can you really have more than 1 of those keys? I would expect at most 1 tuple of nodes with the same key which would greatly simplify the code.
– Imus
Mar 19 at 9:36
A tuple can have, by unique key, one (two or three) element(s) ofXPN,TU, andEFX. You can have another tuple for the same unique key with (almost) the same elements. The data is like that, hence the use of aListand not aSet. For a given unique key, you need to figure it out how many elements ofXPN,TU, andEFX, filling up the tuples whenever you find one of those. You build a new tuple for the same unique key when you find two elements of, for instance,XPN,TU, orEFX...and so on.
– x80486
Mar 19 at 14:24
I don't think I understand your grouping. I can tell what your code is doing ... but why? If a node has a unique key, can you really have more than 1 of those keys? I would expect at most 1 tuple of nodes with the same key which would greatly simplify the code.
– Imus
Mar 19 at 9:36
I don't think I understand your grouping. I can tell what your code is doing ... but why? If a node has a unique key, can you really have more than 1 of those keys? I would expect at most 1 tuple of nodes with the same key which would greatly simplify the code.
– Imus
Mar 19 at 9:36
A tuple can have, by unique key, one (two or three) element(s) of
XPN, TU, and EFX. You can have another tuple for the same unique key with (almost) the same elements. The data is like that, hence the use of a List and not a Set. For a given unique key, you need to figure it out how many elements of XPN, TU, and EFX, filling up the tuples whenever you find one of those. You build a new tuple for the same unique key when you find two elements of, for instance, XPN, TU, or EFX...and so on.– x80486
Mar 19 at 14:24
A tuple can have, by unique key, one (two or three) element(s) of
XPN, TU, and EFX. You can have another tuple for the same unique key with (almost) the same elements. The data is like that, hence the use of a List and not a Set. For a given unique key, you need to figure it out how many elements of XPN, TU, and EFX, filling up the tuples whenever you find one of those. You build a new tuple for the same unique key when you find two elements of, for instance, XPN, TU, or EFX...and so on.– x80486
Mar 19 at 14:24
add a comment |
1 Answer
1
active
oldest
votes
up vote
0
down vote
Not sure why you're making it so hard on yourself. Why not just go through each of the 3 queues individually?
For the first queue, just go through it and make a new Node for each element. Add it to your result list.
For the other 2 queues, check if the index is already in the result list. If it is, add it to that node, otherwise create a new node.
That's exactly what that snippet is doing, but I don't traverse each list separately, but all at once (up to the longest one). The "grouping" has to be done no matter what.
– x80486
Mar 18 at 18:10
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
0
down vote
Not sure why you're making it so hard on yourself. Why not just go through each of the 3 queues individually?
For the first queue, just go through it and make a new Node for each element. Add it to your result list.
For the other 2 queues, check if the index is already in the result list. If it is, add it to that node, otherwise create a new node.
That's exactly what that snippet is doing, but I don't traverse each list separately, but all at once (up to the longest one). The "grouping" has to be done no matter what.
– x80486
Mar 18 at 18:10
add a comment |
up vote
0
down vote
Not sure why you're making it so hard on yourself. Why not just go through each of the 3 queues individually?
For the first queue, just go through it and make a new Node for each element. Add it to your result list.
For the other 2 queues, check if the index is already in the result list. If it is, add it to that node, otherwise create a new node.
That's exactly what that snippet is doing, but I don't traverse each list separately, but all at once (up to the longest one). The "grouping" has to be done no matter what.
– x80486
Mar 18 at 18:10
add a comment |
up vote
0
down vote
up vote
0
down vote
Not sure why you're making it so hard on yourself. Why not just go through each of the 3 queues individually?
For the first queue, just go through it and make a new Node for each element. Add it to your result list.
For the other 2 queues, check if the index is already in the result list. If it is, add it to that node, otherwise create a new node.
Not sure why you're making it so hard on yourself. Why not just go through each of the 3 queues individually?
For the first queue, just go through it and make a new Node for each element. Add it to your result list.
For the other 2 queues, check if the index is already in the result list. If it is, add it to that node, otherwise create a new node.
answered Mar 5 at 9:58
Imus
3,343223
3,343223
That's exactly what that snippet is doing, but I don't traverse each list separately, but all at once (up to the longest one). The "grouping" has to be done no matter what.
– x80486
Mar 18 at 18:10
add a comment |
That's exactly what that snippet is doing, but I don't traverse each list separately, but all at once (up to the longest one). The "grouping" has to be done no matter what.
– x80486
Mar 18 at 18:10
That's exactly what that snippet is doing, but I don't traverse each list separately, but all at once (up to the longest one). The "grouping" has to be done no matter what.
– x80486
Mar 18 at 18:10
That's exactly what that snippet is doing, but I don't traverse each list separately, but all at once (up to the longest one). The "grouping" has to be done no matter what.
– x80486
Mar 18 at 18:10
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188835%2fprocess-n-lists-simultaneously-by-doing-permutations%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I don't think I understand your grouping. I can tell what your code is doing ... but why? If a node has a unique key, can you really have more than 1 of those keys? I would expect at most 1 tuple of nodes with the same key which would greatly simplify the code.
– Imus
Mar 19 at 9:36
A tuple can have, by unique key, one (two or three) element(s) of
XPN,TU, andEFX. You can have another tuple for the same unique key with (almost) the same elements. The data is like that, hence the use of aListand not aSet. For a given unique key, you need to figure it out how many elements ofXPN,TU, andEFX, filling up the tuples whenever you find one of those. You build a new tuple for the same unique key when you find two elements of, for instance,XPN,TU, orEFX...and so on.– x80486
Mar 19 at 14:24