Need help traversing an ArrayList of HashMap - java

I need to loop through an ArrayList and look for a particular "keys" HashMap and return the corresponding "params" HashMap as shown in the screenshot.
This is what I have so far but it's not working
private void getParam() {
List<Map<String, Object>> matrix = transactionInfoMatrix.getMatrixTransactionInfo();
MatrixTransactionInfoKeys key = new MatrixTransactionInfoKeys("OP/OP", "2777", "CT", "NBCTRANSFER", "AMT");
for (Map<String, Object> entry : matrix) {
if (entry.containsValue(key)) {
System.out.println("Found it");
}
}
}
Here is the MatrixTransactionInfoKeys class, but I have removed the getters and setters for the purposes of this post.
public class MatrixTransactionInfoKeys {
private String accountType;
private String applicationSourceCode;
private String operationType;
private String service;
private String transactionType;
public MatrixTransactionInfoKeys(String accountType, String applicationSourceCode, String operationType, String service, String transactionType) {
this.accountType = accountType;
this.applicationSourceCode = applicationSourceCode;
this.operationType = operationType;
this.service = service;
this.transactionType = transactionType;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((accountType == null) ? 0 : accountType.hashCode());
result = prime * result + ((applicationSourceCode == null) ? 0 : applicationSourceCode.hashCode());
result = prime * result + ((operationType == null) ? 0 : operationType.hashCode());
result = prime * result + ((service == null) ? 0 : service.hashCode());
result = prime * result + ((transactionType == null) ? 0 : transactionType.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
MatrixTransactionInfoKeys other = (MatrixTransactionInfoKeys) obj;
if (accountType == null) {
if (other.accountType != null) {
return false;
}
} else if (!accountType.equals(other.accountType)) {
return false;
}
if (applicationSourceCode == null) {
if (other.applicationSourceCode != null) {
return false;
}
} else if (!applicationSourceCode.equals(other.applicationSourceCode)) {
return false;
}
if (operationType == null) {
if (other.operationType != null) {
return false;
}
} else if (!operationType.equals(other.operationType)) {
return false;
}
if (service == null) {
if (other.service != null) {
return false;
}
} else if (!service.equals(other.service)) {
return false;
}
if (transactionType == null) {
return other.transactionType == null;
} else
return transactionType.equals(other.transactionType);
}
#Override
public String toString() {
return "MatrixTransactionInfoKeys [service=" + service + ", applicationSourceCode=" + applicationSourceCode
+ ", transactionType=" + transactionType + ", operationType=" + operationType + ", accountType=" + accountType + "]";
}
}

Remaking this answer, since I originally misinterpreted the question.
Based on the code supplied, assuming the MatrixTransactionInfoKeys in the map actually match and are created similarly, I get "Found it" in the output of this:
public class MatrixCheck {
public TransactionInfoMatrix transactionInfoMatrix;
private void getParam() {
List<Map<String, Object>> matrix = transactionInfoMatrix.getMatrixTransactionInfo();
MatrixTransactionInfoKeys key = new MatrixTransactionInfoKeys("OP/OP", "2777", "CT", "NBCTRANSFER", "AMT");
for (Map<String, Object> entry : matrix) {
if (entry.containsValue(key)) {
System.out.println("Found it");
}
}
}
public static void main( String[] args ) {
MatrixCheck matrixCheck = new MatrixCheck();
matrixCheck.transactionInfoMatrix = new TransactionInfoMatrix();
matrixCheck.transactionInfoMatrix.transactionInfo = new ArrayList<>();
matrixCheck.transactionInfoMatrix.transactionInfo.add( new HashMap<>() );
// Add the object to the map exactly as how it is
// constructed in the "getParam" portion
matrixCheck.transactionInfoMatrix.transactionInfo.get(0).put( "MyTest", new MatrixTransactionInfoKeys("OP/OP", "2777", "CT", "NBCTRANSFER", "AMT") );
matrixCheck.getParam();
}
static class TransactionInfoMatrix {
List<Map<String,Object>> transactionInfo;
public List<Map<String,Object>> getMatrixTransactionInfo() {
return transactionInfo;
}
}
static class MatrixTransactionInfoKeys {
private String accountType;
private String applicationSourceCode;
private String operationType;
private String service;
private String transactionType;
public MatrixTransactionInfoKeys(String accountType, String applicationSourceCode, String operationType, String service, String transactionType) {
this.accountType = accountType;
this.applicationSourceCode = applicationSourceCode;
this.operationType = operationType;
this.service = service;
this.transactionType = transactionType;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((accountType == null) ? 0 : accountType.hashCode());
result = prime * result + ((applicationSourceCode == null) ? 0 : applicationSourceCode.hashCode());
result = prime * result + ((operationType == null) ? 0 : operationType.hashCode());
result = prime * result + ((service == null) ? 0 : service.hashCode());
result = prime * result + ((transactionType == null) ? 0 : transactionType.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
MatrixTransactionInfoKeys other = (MatrixTransactionInfoKeys) obj;
if (accountType == null) {
if (other.accountType != null) {
return false;
}
} else if (!accountType.equals(other.accountType)) {
return false;
}
if (applicationSourceCode == null) {
if (other.applicationSourceCode != null) {
return false;
}
} else if (!applicationSourceCode.equals(other.applicationSourceCode)) {
return false;
}
if (operationType == null) {
if (other.operationType != null) {
return false;
}
} else if (!operationType.equals(other.operationType)) {
return false;
}
if (service == null) {
if (other.service != null) {
return false;
}
} else if (!service.equals(other.service)) {
return false;
}
if (transactionType == null) {
return other.transactionType == null;
} else
return transactionType.equals(other.transactionType);
}
#Override
public String toString() {
return "MatrixTransactionInfoKeys [service=" + service + ", applicationSourceCode=" + applicationSourceCode
+ ", transactionType=" + transactionType + ", operationType=" + operationType + ", accountType=" + accountType + "]";
}
}
}

Related

Serialization in the hazelcast jet

I'm getting the following error when I tried to processing the data from hazelcast jet.
Caused by: java.lang.IllegalArgumentException: Invalid lambda deserialization
at com.example.LearnJet.joins.LeftJoins.$deserializeLambda$(LeftJoins.java:1)
... 59 more
Here is the code:-
AddToCart1 instance
public class AddToCart1 implements Serializable {
private int number;
private String cart;
public AddToCart1() {
super();
// TODO Auto-generated constructor stub
}
public int getNumber() {
return number;
}
public AddToCart1(int number, String cart) {
super();
this.number = number;
this.cart = cart;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((cart == null) ? 0 : cart.hashCode());
result = prime * result + number;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AddToCart1 other = (AddToCart1) obj;
if (cart == null) {
if (other.cart != null)
return false;
} else if (!cart.equals(other.cart))
return false;
if (number != other.number)
return false;
return true;
}
public void setNumber(int number) {
this.number = number;
}
public String getCart() {
return cart;
}
public void setCart(String cart) {
this.cart = cart;
}
}
PageVisit1 instance
public class PageVisit1 implements Serializable {
/**
*
*/
private int number;
private String pageName;
public PageVisit1() {
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + number;
result = prime * result + ((pageName == null) ? 0 : pageName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PageVisit1 other = (PageVisit1) obj;
if (number != other.number)
return false;
if (pageName == null) {
if (other.pageName != null)
return false;
} else if (!pageName.equals(other.pageName))
return false;
return true;
}
public PageVisit1(int number, String pageName) {
super();
this.number = number;
this.pageName = pageName;
}
/**
* #return the number
*/
public int getNumber() {
return number;
}
/**
* #param number the number to set
*/
public void setNumber(int number) {
this.number = number;
}
/**
* #return the pageName
*/
public String getPageName() {
return pageName;
}
/**
* #param pageName the pageName to set
*/
public void setPageName(String pageName) {
this.pageName = pageName;
}
}
Here is the main class
public class LeftJoins {
public static void main(String[] args) throws InvocationTargetException {
JetInstance jet = Jet.bootstrappedInstance();
IList<AddToCart1> addToCartList = jet.getList("cart");
IList<PageVisit1> paymentList = jet.getList("page");
// AddToCartData
AddToCart1 ad1 = new AddToCart1();
ad1.setNumber(1);
ad1.setCart("lulu bazar");
AddToCart1 ad2 = new AddToCart1();
ad2.setNumber(2);
ad2.setCart("krishna bazar");
AddToCart1 ad3 = new AddToCart1();
ad3.setNumber(3);
ad3.setCart("ram bazar");
addToCartList.add(ad1);
addToCartList.add(ad2);
addToCartList.add(ad3);
// Page Data
PageVisit1 pg1 = new PageVisit1();
pg1.setNumber(1);
pg1.setPageName("k login");
PageVisit1 pg2 = new PageVisit1();
pg2.setNumber(2);
pg2.setPageName("plogin");
paymentList.add(pg1);
paymentList.add(pg2);
// creating a piple-line here
Pipeline p = Pipeline.create();
BatchStageWithKey<AddToCart1, Object> cart = p.readFrom(Sources.<AddToCart1>list("cart"))
.groupingKey(cart1 -> cart1.getNumber());
BatchStageWithKey<PageVisit1, Object> page = p.readFrom(Sources.<PageVisit1>list("page"))
.groupingKey(page1 -> page1.getNumber());
BatchStage<Tuple2<List<PageVisit1>, List<AddToCart1>>> joinedLists1 = page.aggregate2(toList(), cart, toList())
.map(Entry::getValue);
BatchStage<Tuple2<List<PageVisit1>, List<AddToCart1>>> m = joinedLists1.filter(pair -> !pair.f0().isEmpty());
m.writeTo(Sinks.logger());
jet.newJob(p).join();
// joinedLists.filter(pair -> !pair.isEmpty());
}
The code is obviously incomplete, because there's no page variable so that page.aggregate2(...) shouldn't compile.
For this reason, I'm unable to point you to the exact line where the issue occurs. However, the error message tells you're using a "standard" lambda from the JDK that isn't Serializable, whereas you should use the ones from Jet, which are.
Please check this package.
EDIT:
I've created a dedicated GitHub project with the above code.
Everything works as expected. The 2 tuples are displayed correctly in the log:
09:33:59.974 [ INFO] [c.h.j.i.c.WriteLoggerP] [05d8-7d0a-e3c0-0001/loggerSink#0] ([ch.frankel.so.PageVisit1#c544b8f8], [ch.frankel.so.AddToCart1#41c722ed])
09:33:59.974 [ INFO] [c.h.j.i.c.WriteLoggerP] [05d8-7d0a-e3c0-0001/loggerSink#0] ([ch.frankel.so.PageVisit1#58fbcb54], [ch.frankel.so.AddToCart1#c666a2c4])

Map (with operation) Stream java 8, nestedList

I'm looking for minimumlistPerValueOld working translate to minimumlistPerValueNew in the method getOptimizedTreeNodeResample(TreeNodeResample in, List<Integer> listSampleRateFinal)
/*I need to find the list that by adding it to the nested list,
the minimum number of operations required*/
private static TreeNodeResample getOptimizedTreeNodeResample(TreeNodeResample in, List<Integer> listSampleRateFinal) {
TreeNodeResample out = new TreeNodeResample(null);
listSampleRateFinal.forEach(sampleRateFinal -> {
List<List<NodeResample>> nestedListPerValue = getFilteredNestedListsValue(in, sampleRateFinal);
Long lastMinimum = Long.MAX_VALUE;
List<NodeResample> minimumlistPerValue = null;
for (List<NodeResample> listPerValue : nestedListPerValue) {
Long accumulator = addCalc(out.getNestedListsValue(), listPerValue)
.stream()
.map(nodeResample -> (long) nodeResample.getNumResampleOperations())
.mapToLong(Long::longValue).sum();
if (accumulator < lastMinimum) {
lastMinimum = accumulator;
minimumlistPerValue = listPerValue;
}
}
out.addListValue(minimumlistPerValue);
});
return out;
}
I believe I need to map listPerValue, as you can see listPerValue is the type List<NodeResample>
listPerValue -> {
TreeNodeResample temp = new TreeNodeResample(null);
temp.setNestedListsValue(out.getNestedListsValue());
temp.addListValue(listPerValue);
return temp.getListNodes();// return List<TreeNodeResample> type
}
Or map (to the same object type)
listPerValue -> {
TreeNodeResample temp = new TreeNodeResample(null);
temp.setNestedListsValue(out.getNestedListsValue());
temp.addListValue(listPerValue);
List<NodeResample> childsValues = temp.getListNodes()
.stream()
.map(node -> node.getValue())
.collect(Collectors.toList());
return childsValues;// return List<NodeResample> type
}
The complete TreeNodeResample class:
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
public class TreeNodeResample {
TreeNodeResample parent;
List<TreeNodeResample> children;
NodeResample value;
public TreeNodeResample(TreeNodeResample parent) {
this.parent = parent;
children = new ArrayList<>();
}
public TreeNodeResample(TreeNodeResample parent, NodeResample value) {
this.parent = parent;
children = new ArrayList<>();
this.value = value;
}
public void addChild(TreeNodeResample node) {
if (node != null && node.getValue() != null) {//REVIEW (node.getValue() != null) is needed?
if (children.stream().noneMatch(child -> Objects.equals(child.getValue(), node.getValue()))) {
children.add(node);
}
}
}
public TreeNodeResample getParent() {
return parent;
}
public void cleanChildren() {
children = new ArrayList<>();
}
public int getChildrenCount() {
return children.size();
}
public TreeNodeResample getChildrenAt(int position) {
if (children.size() > position && position > -1) {
return children.get(position);
}
return null;
}
public List<TreeNodeResample> getChildren() {
return children;
}
public NodeResample getValue() {
return value;
}
public boolean isLeaf() {
return (children.isEmpty());
}
public List<TreeNodeResample> getLeafs() {
return getLeafs(this);
}
public void addListValue(List<NodeResample> listValue) {
addListValue(this, listValue);
}
public TreeNodeResample getNode(NodeResample value) {
return getNode(this, value);
}
public List<NodeResample> getListValues() {
return getListNodes().stream().map(node -> node.getValue()).collect(Collectors.toList());
}
public List<TreeNodeResample> getListNodes() {
List<TreeNodeResample> listNodes = new ArrayList<>();
getListNodes(this, listNodes);
return listNodes;
}
public List<List<NodeResample>> getNestedListsValue() {
return getNestedListsValue(this);
}
public void setNestedListsValue(List<List<NodeResample>> nestedListsValue) {
setNestedListsValue(this, nestedListsValue);
}
public List<List<NodeResample>> getFilteredNestedListsValue(int sampleRateTarget) {
return getFilteredNestedListsValue(this, sampleRateTarget);
}
public TreeNodeResample getOptimizedTreeNodeResample(List<Integer> listSampleRateFinal) {
return getOptimizedTreeNodeResample(this, listSampleRateFinal);
}
public static void addListValue(TreeNodeResample parent, List<NodeResample> listValue) {
if (listValue != null) {
TreeNodeResample node = parent;
for (NodeResample child : listValue) {
node = getNode(node, child);
}
}
}
public static TreeNodeResample getNode(TreeNodeResample parent, NodeResample value) {
if (parent != null) {//REVIEW (value != null) is needed?
TreeNodeResample node = parent.getChildren().stream()
.filter(child -> child != null)
.filter(child -> Objects.equals(child.getValue(), value))
.findAny().orElse(null);
if (node != null) {
return node;
}
node = new TreeNodeResample(parent, value);
parent.addChild(node);
return node;
} else {
return null;
}
}
public static List<TreeNodeResample> getListNodes(TreeNodeResample parent) {
List<TreeNodeResample> listNodes = new ArrayList<>();
getListNodes(parent, listNodes);
return listNodes;
}
public static void getListNodes(TreeNodeResample parent, List<TreeNodeResample> listNodes) {
if (parent != null) {
listNodes.add(parent);
parent.getChildren().forEach(child -> getListNodes(child, listNodes));
}
}
public static List<List<NodeResample>> getNestedListsValue(TreeNodeResample parent) {
List<TreeNodeResample> listLeafs = getLeafs(parent);
List<List<NodeResample>> nestedListsValues = listLeafs.stream()
.map(leaf -> getParentsListValue(leaf))
.peek(listNodeResample -> {
//System.out.println(Arrays.toString(listNodeResample.toArray()) + System.lineSeparator() + System.lineSeparator());
})
.collect(Collectors.toList());
return nestedListsValues;
}
public static void setNestedListsValue(TreeNodeResample parent, List<List<NodeResample>> nestedListsValue) {
parent.cleanChildren();
nestedListsValue.stream()
.forEachOrdered(listValue -> {
addListValue(parent, listValue);
});
}
public static List<NodeResample> getParentsListValue(TreeNodeResample leaf) {
List<NodeResample> listValue = new ArrayList<>();
if (leaf != null) {
listValue.add(leaf.getValue());
TreeNodeResample node = leaf.getParent();
while (node != null && node.getValue() != null) {
listValue.add(0, node.getValue());
node = node.getParent();
}
}
return listValue;
}
public static List<List<NodeResample>> getFilteredNestedListsValue(TreeNodeResample parent, int sampleRateTarget) {
List<TreeNodeResample> listNodes = getListNodes(parent)
.stream()
.filter(treeNodeResample -> treeNodeResample.getValue() != null)
.filter(treeNodeResample -> treeNodeResample.getValue().getSampleRateTarget() == sampleRateTarget)
.collect(Collectors.toList());
List<List<NodeResample>> nestedListsValues = listNodes.stream()
.map(node -> getParentsListValue(node))
.collect(Collectors.toList());
return nestedListsValues;
}
private static TreeNodeResample getOptimizedTreeNodeResample(TreeNodeResample in, List<Integer> listSampleRateFinal) {
TreeNodeResample out = new TreeNodeResample(null);
listSampleRateFinal.forEach(sampleRateFinal -> {
List<List<NodeResample>> nestedListPerValue = getFilteredNestedListsValue(in, sampleRateFinal);
Long lastMinimum = Long.MAX_VALUE;
List<NodeResample> minimumlistPerValue = null;
for (List<NodeResample> listPerValue : nestedListPerValue) {
Long accumulator = addCalc(out.getNestedListsValue(), listPerValue)
.stream()
.map(nodeResample -> (long) nodeResample.getNumResampleOperations())
.mapToLong(Long::longValue).sum();
if (accumulator < lastMinimum) {
lastMinimum = accumulator;
minimumlistPerValue = listPerValue;
}
}
out.addListValue(minimumlistPerValue);
});
return out;
}
private static List<NodeResample> addCalc(List<List<NodeResample>> nestednestedListValue, List<NodeResample> listPerValue) {
TreeNodeResample temp = new TreeNodeResample(null);
temp.setNestedListsValue(nestednestedListValue);
temp.addListValue(listPerValue);
return temp.getListNodes().stream()
.map(node -> node.getValue())
.filter(nodeResample -> nodeResample != null)
.collect(Collectors.toList());
}
public static List<TreeNodeResample> getLeafs(TreeNodeResample parent) {
List<TreeNodeResample> listLeafs = new ArrayList<>();
getLeafs(parent, listLeafs);
return listLeafs;
}
private static void getLeafs(TreeNodeResample parent, List<TreeNodeResample> listLeafs) {
if (parent != null && listLeafs != null) {
if (parent.isLeaf()) {
listLeafs.add(parent);
} else {
parent.getChildren().forEach(child -> getLeafs(child, listLeafs));
}
}
}
#Override
public String toString() {
return "TreeNodeResample{" + "value=" + value + '}';
}
public static void tempPrintNested(List<List<NodeResample>> nestedListNodeResample) {
System.out.println(" List<List<NodeResample>> nestedListNodeResample = Arrays.asList(");
for (int o = 0; o < nestedListNodeResample.size(); o++) {
List<NodeResample> listNodeResample = nestedListNodeResample.get(o);
System.out.println(" Arrays.asList(");
for (int i = 0; i < listNodeResample.size(); i++) {
NodeResample nodeResample = listNodeResample.get(i);
if (nodeResample != null) {
System.out.print(" " + nodeResample.getCreator());
if (i < listNodeResample.size() - 1) {
System.out.println(",");
} else {
System.out.println("\n )");
}
}
}
if (o < nestedListNodeResample.size() - 1) {
System.out.println(" ,");
}
}
System.out.println(" );");
}
}
The another NodeResample class
public class NodeResample {
private int incrementL;
private int decrementM;
private int sampleRateSource;
private int sampleRateTarget;
private double maxPassFreq;
private Integer filterSize;
private Integer numResampleOperations;
public NodeResample(int incrementL, int decrementM, int sampleRateSource, int sampleRateTarget, double maxPassFreq, Integer filterSize, Integer numResampleOperations) {
this.incrementL = incrementL;
this.decrementM = decrementM;
this.sampleRateSource = sampleRateSource;
this.sampleRateTarget = sampleRateTarget;
this.maxPassFreq = maxPassFreq;
this.filterSize = filterSize;
this.numResampleOperations = numResampleOperations;
}
public int getIncrementL() {
return incrementL;
}
public void setIncrementL(int incrementL) {
this.incrementL = incrementL;
}
public int getDecrementM() {
return decrementM;
}
public void setDecrementM(int decrementM) {
this.decrementM = decrementM;
}
public int getSampleRateSource() {
return sampleRateSource;
}
public void setSampleRateSource(int sampleRateSource) {
this.sampleRateSource = sampleRateSource;
}
public int getSampleRateTarget() {
return sampleRateTarget;
}
public void setSampleRateTarget(int sampleRateTarget) {
this.sampleRateTarget = sampleRateTarget;
}
public double getMaxPassFreq() {
return maxPassFreq;
}
public void setMaxPassFreq(double maxPassFreq) {
this.maxPassFreq = maxPassFreq;
}
public Integer getFilterSize() {
return filterSize;
}
public void setFilterSize(Integer filterSize) {
this.filterSize = filterSize;
}
public Integer getNumResampleOperations() {
return numResampleOperations;
}
public void setNumResampleOperations(Integer numResampleOperations) {
this.numResampleOperations = numResampleOperations;
}
#Override
public String toString() {
return "NodeResample{" + "L=" + incrementL + ", M=" + decrementM
+ ", Source=" + sampleRateSource + ", Target=" + sampleRateTarget
+ ", filterSize=" + filterSize + ", numResampleOperations=" + numResampleOperations
+ "} ";
}
public String getCreator() {
return "new NodeResample(" + incrementL + "," + decrementM + "," + sampleRateSource + "," + sampleRateTarget + "," + "0.0" + "," + filterSize + "," + numResampleOperations
+ ")";
}
#Override
public int hashCode() {
int hash = 3;
return hash;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final NodeResample other = (NodeResample) obj;
if (this.incrementL != other.incrementL) {
return false;
}
if (this.decrementM != other.decrementM) {
return false;
}
if (this.sampleRateSource != other.sampleRateSource) {
return false;
}
if (this.sampleRateTarget != other.sampleRateTarget) {
return false;
}
if (!Objects.equals(this.filterSize, other.filterSize)) {
return false;
}
return true;
}
}
I want to translate using Java Streams
But, I'm frustrated...
List<NodeResample> minimumlistPerValueNew = nestedListPerValue.stream()
.min(
Comparator.comparingLong(map(listPerValue -> {
TreeNodeResample temp = new TreeNodeResample(null);
temp.setNestedListsValue(out.getNestedListsValue());
temp.addListValue(listPerValue);
return temp.getListNodes();
})
//.map(node -> node::getValue)
.filter(nodeResample -> nodeResample != null)
.mapToLong(NodeResample::getNumResampleOperations).sum())
)
.orElse(Collections.emptyList());
RESUMED SITUATION
public CustomObject wrapperMethod(List<CustomObject> listCustomObjects) {
Long lastMinimum = Long.MAX_VALUE;
CustomObject minCustomObject;
for (CustomObject customObject : listCustomObjects) {
Long returnedValue = anyMethodReturningLong(customObject);
if (returnedValue < lastMinimum) {
lastMinimum = returnedValue;
minCustomObject = customObject;
}
}
return minCustomObject;
}
You can try Stream.reduce() also for your problem.
What I understand from your problem is that there is a nestedList and out of those inner Lists you want to return the list which matches your minimum criteria.
For e.g let say we have nested list like this [[1,2,4],[5,6,7,8,9,10],[11,12]] and now you want return the list with smallest list.size(). Try below code :
import java.util.*;
import java.util.stream.*;
public class Main
{
public static void main(String[] args) {
List<List<Integer>> nestedList = Arrays.asList(
Arrays.asList(1,2,4),
Arrays.asList(5,6,7,8,9,2,5),
Arrays.asList(10,11,12,13,0));
Optional<List<Integer>> oplist = nestedList.stream()
.reduce((list1, list2) -> list1.size() < list2.size() ? list1 : list2);
oplist.ifPresent(System.out::println);
}
}
Output : [1,2,4]
Hope you get the idea behind the approach. Now you can try comparison check inside reduce method and check if it works for you.
Solution for RESUMED SITUATION
//Using .reduce() method
Optional<CustomObject> minCustomObjectList = listCustomObjects.stream()
.reduce((lastMinimum, returnedValue) -> anyMethodReturningLong(returnedValue) < anyMethodReturningLong(lastMinimum) ? returnedValue : lastMinimum);
minCustomObjectList.ifPresent(e -> System.out.println("Minimum Object using reduce method "+e.toString()));
//Using .min() method
CustomObject minCustomObject = listCustomObjects.stream()
.min(Comparator.comparingLong(e -> anyMethodReturningLong(e))).get();
System.out.printf("Minimum Object using min method"+minCustomObject.toString());

What is the efficient way to compare two lists in Java?

I have a program which gets list of java object from db and compares it to the old list that have already been retrieved, and finds the delta (difference) elements in it and returns.
I am wondering if there is best way to do this rather than just using Set methods Union(), Intersection() etc., and avoiding out of memory errors?
Size of the list can be 200k.
I am using Spring 3.2.8.RELEASE version in my project.
public class Tester {
private List<AddressInfo> oldListOfAddresses;
#Scheduled(cron="0 1 6 * * ?") // 6 AM everyday
public Map<String, AddressInfo> getCompany() {
try {
Map<String, AddressInfo> companyMap = new HashMap<>();
String sql = "Some sql query which return Address Info.";
List<AddressInfo> newListOfAddresses = jdbcTemplate.query(sql, new Object[0],
new FacilityNewMapper());
if (newListOfAddresses == null || newListOfAddresses.size() = 0) {
throw new FacilityLookUpException("List of clinic Info from facilities is empty...");
} else {
// I have to find the delta of new list and old list here.
// I need an efficient (Space and Time) way of finding delta.
List<AddressInfo> deltaList = newListOfAddresses - oldListOfAddresses; //Something like this
for (AddressInfo comp : deltaList) {
if (comp != null) {
companyMap.put(comp.getLocationId(), comp);
}
}
oldListOfAddresses = newListOfAddresses;
}
return companyMap;
} catch (Exception e) {
throw new CompanyLookUpException(
"List of company addresses is empty..." + e.getMessage());
}
}
}
AddressInfo bean.
public class AddressInfo{
private String locationId;
private String streetName;
private String city;
private String state;
private String country;
public String getLocationId() {
return locationId;
}
public void setLocationId(String locationId) {
this.locationId = locationId;
}
public String getStreetName() {
return streetName;
}
public void setStreetName(String streetName) {
this.streetName = streetName;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((city == null) ? 0 : city.hashCode());
result = prime * result + ((country == null) ? 0 : country.hashCode());
result = prime * result + ((locationId == null) ? 0 : locationId.hashCode());
result = prime * result + ((state == null) ? 0 : state.hashCode());
result = prime * result + ((streetName == null) ? 0 : streetName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AddressInfo other = (AddressInfo) obj;
if (city == null) {
if (other.city != null)
return false;
} else if (!city.equals(other.city))
return false;
if (country == null) {
if (other.country != null)
return false;
} else if (!country.equals(other.country))
return false;
if (locationId == null) {
if (other.locationId != null)
return false;
} else if (!locationId.equals(other.locationId))
return false;
if (state == null) {
if (other.state != null)
return false;
} else if (!state.equals(other.state))
return false;
if (streetName == null) {
if (other.streetName != null)
return false;
} else if (!streetName.equals(other.streetName))
return false;
return true;
}
}
I don't think so (Note: I assume that the order of the list has no importance). For example, the fastest way to do this without using the set is to sort both of the lists which will cost you O(nlogn) and then iterate over them comparing each element and save those that don't have a pair. In case of Set, you will basically iterate over each element and look for it in the second set so the iteration is O(n) and the search is O(1). In the end we have O(nlogn) > O(n) the set wins
This should work fine for creating difference between two list.
Here I am creating a set and adding all elements of newList.
Then whichever elements are part of oldList I am removing them.
Set< AddressInfo > findDiffOfTwoList( List< AddressInfo > newList, List< AddressInfo > oldList) {
Set<AddressInfo> set = new HashSet<>();
set.addAll(newList);
for(AddressInfo address:oldList){
set.remove(address);
}
return set;
}
Assuming AddressInfo implements equals and hashCode properly, and items in each list are unique, the following function can find the delta in linear time:
Set< AddressInfo > findDiff(final List< AddressInfo > newListOfAddresses, final List< AddressInfo > oldListOfAddresses) {
Map< AddressInfo, Boolean > map = new HashMap<>(newListOfAddresses.size());
for ( AddressInfo addressInfo : newListOfAddresses ) {
map.put( addressInfo, TRUE );
}
for ( AddressInfo addressInfo : oldListOfAddresses ) {
map.remove( addressInfo );
}
return map.keySet();
}

Type inference not working in Eclipse Luna

I have newly started off with Java 8 and I'm trying out some examples on Collectors. I'm following the book, Java 8 in action. I have got a doubt regarding type inference :
I have used basic model classes Student, Name to create examples. PFB the details:
package com.learning.fundamentals;
import java.util.ArrayList;
import java.util.List;
public class Student {
public enum Gender {
MALE, FEMALE;
}
private String id;
private Name name;
private Gender gender;
public Student(String id, Name name, Gender gender) {
this.id = id;
this.name = name;
this.gender = gender;
}
public String getId() {
return id;
}
public Name getName() {
return name;
}
public Gender getGender() {
return gender;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((gender == null) ? 0 : gender.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (gender != other.gender)
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
#Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", gender=" + gender
+ "]";
}
}
package com.learning.fundamentals;
public class Name {
private String firstName;
private String middleName;
private String lastName;
public Name(String firstName, String middleName, String lastName) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getMiddleName() {
return middleName;
}
public String getLastName() {
return lastName;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result
+ ((lastName == null) ? 0 : lastName.hashCode());
result = prime * result
+ ((middleName == null) ? 0 : middleName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Name other = (Name) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
if (middleName == null) {
if (other.middleName != null)
return false;
} else if (!middleName.equals(other.middleName))
return false;
return true;
}
#Override
public String toString() {
return "Name [firstName=" + firstName + ", middleName=" + middleName
+ ", lastName=" + lastName + "]";
}
}
Now I have a list of Students like this
List<Student> studentList = getStudents(); //some method to create the list
Now, let's try out an grouping example. This is a multilevel grouping, first I'm grouping it using Gender and then some criteria on first name (not important). Here is the code :
Map<Student.Gender, Map<String, List<Student>>> studentsByGenderName =
studentList.stream()
.collect(Collectors.groupingBy(Student::getGender,
Collectors.groupingBy(std -> std.getName().getFirstName().substring(0, 4))));
This gives me an error at the second collector, stating "The method getName() is undefined for the type Object". Now, I was able to resolve the issue by providing the type of 'std' like this:
Map<Student.Gender, Map<String, List<Student>>> studentsByGenderName =
studentList.stream()
.collect(Collectors.groupingBy(Student::getGender,
Collectors.groupingBy((Student std) -> std.getName().getFirstName().substring(0, 4))));
My question is why can't java infer the type of the argument in lambda expression used in the second collector while it's able to do that for the first collector?

Overriding equals() for use with Linked List

I have two methods for looking up the index of a particular element in a linked list. I'm trying to use contais() and indexOf() to find the index. I am unsure how to override equals() to suit my need. One method finds the index based on surname and initials the other just the telephone number. Here are my methods:
#Override
public int lookupNumber(String surname, String initials) {
Entry entry1 = new Entry(surname, initials);
if (listDirectory.contains(entry1)) {
int index = listDirectory.indexOf(entry1);
return index;
}
else {
return -1;
}
}
#Override
public int lookupName(int extension) {
Entry entry1 = new Entry(Integer.toString(extension));
if (listDirectory.contains(entry1)) {
int index = listDirectory.indexOf(entry1);
return index;
}
else {
return -1;
}
}
I've tried to use the equals() and hashCode() that eclipse provides:
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Entry other = (Entry) obj;
if (extension == null) {
if (other.extension != null)
return false;
} else if (!extension.equals(other.extension))
return false;
if (initals == null) {
if (other.initals != null)
return false;
} else if (!initals.equals(other.initals))
return false;
if (surname == null) {
if (other.surname != null)
return false;
} else if (!surname.equals(other.surname))
return false;
return true;
}
But it won't work for both my methods, as it compares all the variables in the objects not just the ones I need it to compare. What is the correct logic for this?
Help much appreciated, thanks.
Update - here is my full Entry class -
public class Entry {
private String surname;
private String initals;
private String extension;
public Entry(String surname, String initals,String extension) {
this.surname = surname;
this.initals = initals;
this.extension = extension;
}
public Entry(String surname,String initals){
this.surname = surname;
this.initals = initals;
}
public Entry(String extension) {
this.extension = extension;
}
public String getInitals(){
return initals;
}
public String getSurname(){
return surname;
}
public String getExtension(){
return extension;
}
public void setExtension(String extension) {
this.extension = extension;
}
public String toString(){
return surname + "\t " + initals + "\t" + extension;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((extension == null) ? 0 : extension.hashCode());
result = prime * result + ((initals == null) ? 0 : initals.hashCode());
result = prime * result + ((surname == null) ? 0 : surname.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Entry other = (Entry) obj;
if (extension == null) {
if (other.extension != null)
return false;
} else if (!extension.equals(other.extension))
return false;
if (initals == null) {
if (other.initals != null)
return false;
} else if (!initals.equals(other.initals))
return false;
if (surname == null) {
if (other.surname != null)
return false;
} else if (!surname.equals(other.surname))
return false;
return true;
}
}
Update - My problem is in my lookupNumber() method I want to find elements by (initials,surname) whereas in my lookupNumber() I want to find elements by (extension). How would I do this?
The Java Object class contains an equals() method of its own, and the Entry class should be the blueprint for objects of type Entry. Java inheritance is such that all classes inherit from the Object class, which is of little use to many of us. Really all you would need is
#Override
public boolean equals(Entry otherEntry)
{
if(!(this.surname.equals(otherEntry.getSurname()))
return false;
else if(!(this.initials.equals(otherEntry.getInitials()))
return false;
else if(!(this.extension.equals(otherEntry.getExtension()))
return false;
else
return true;
}
The above code just checks for inequality amongst the instance variables, returning false upon any one not equal.

Categories