Reputation: 838
I have two lists ( List1 and List2) containing objects of type Column. Column has two private variables - Name and Type. The intersection of List1 and List2 is done by Column's name. For example:
List1 = { Column (name = "A", type = "STRING"), Column (name = "B", type = "INT") }
List2 = { Column (name = "A", type = "STRING"), Column (name = "D", type = "INT") }
then intersection of List1 and List2 = { Column (name = "A", type = "STRING") }
How can I efficiently write code in Java 8 without using a double for loop (O(n^2)) to check whether an intersection is valid (if it is not valid, then I would like to know the Column names along with conflicting types, if it is valid, just returning True is good enough for me - I don't need the intersection itself). A valid intersection is defined as follows: the columns in the intersection done by comparing the field name, must have the same type. For example, the following is invalid:
List1 = { Column (name = "A", type = "STRING"), Column (name = "B", type = "INT") }
List2 = { Column (name = "A", type = "INT"), Column (name = "D", type = "INT") }
then an invalid intersection of List1 and List2 = { Column (name = "A", type = "STRING") } since the types do not match. Another way of thinking about it is Given a list of columns in a List1 and a list of columns in List2, I would like to check whether columns which are in both List1 and List2 have the same type.
First attempt:
for (final Column newColumn : newMySQLTableMetaData.getColumns()) {
for (final Column originalColumn : originalMySQLTableMetaData.getColumns()) {
if (newColumn.getName().equals(originalColumn.getName())) {
if (!newColumn.getType().equals(ColumnTypeConverter.toLogicalColumnType(originalColumn.getType()))) {
throw new UploadException("The column types have a mismatch. Original column" +
" named " + originalColumn.getName() + " a type of " + originalColumn.getType().toString() + " " +
"while new column with the same name has a type of " + newColumn.getType().toString());
}
}
}
}
Upvotes: 1
Views: 146
Reputation: 46422
Put all elements from list1
into a HashMap
index by name
. Go throw the second list and look if there's a matching column from the first one (O(1)
per element). If so, check for conflict.
private List<String> conflictList = new ArrayList<String>();
private final Map<String, Column> map = new HashMap<>();
for (Column c1: list1) map.put(c1.name, c1);
for (Column c2: list2) {
Column c1 = map.put(c2.name, c2);
if (c1==null) continue;
if (c1.type.equals(c2.type)) continue;
conflictList.add(c1); // or add the name only or both elements or whatever
}
If conflictList
is empty, then you've won. If you don't care about the details, return early instead of processing the remaining elements.
Upvotes: 2