Skip to content

Commit d52ebde

Browse files
johnmayegonw
authored andcommitted
Replace usages of MultiMap - the computeIfAbsent and getOrDefault APIs of Map now make this construct on vanialla JDK easy. We need a slight tweak to our Cycle comparator since TreeMulitmap keeps things sorted by keys and then values. Since the key is just the length we can keep things equivalent by first comparing the length.
1 parent 5a5d384 commit d52ebde

File tree

8 files changed

+119
-109
lines changed

8 files changed

+119
-109
lines changed

app/depict/src/main/java/org/openscience/cdk/depict/Abbreviations.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323

2424
package org.openscience.cdk.depict;
2525

26-
import com.google.common.collect.ArrayListMultimap;
27-
import com.google.common.collect.Multimap;
2826
import org.openscience.cdk.CDKConstants;
2927
import org.openscience.cdk.config.Elements;
3028
import org.openscience.cdk.exception.CDKException;
@@ -400,7 +398,7 @@ public List<Sgroup> generate(final IAtomContainer mol) {
400398
}
401399

402400
List<IAtomContainer> fragments = generateFragments(mol);
403-
Multimap<IAtom, Sgroup> sgroupAdjs = ArrayListMultimap.create();
401+
Map<IAtom, List<Sgroup>> sgroupAdjs = new HashMap<>();
404402

405403
for (IAtomContainer frag : fragments) {
406404
try {
@@ -445,7 +443,8 @@ else if (attachBond.getEnd().equals(atom))
445443
}
446444

447445
if (attachAtom != null)
448-
sgroupAdjs.put(attachAtom, sgroup);
446+
sgroupAdjs.computeIfAbsent(attachAtom, k -> new ArrayList<>())
447+
.add(sgroup);
449448
newSgroups.add(sgroup);
450449

451450
} catch (CDKException e) {
@@ -477,7 +476,7 @@ else if (attachBond.getEnd().equals(atom))
477476

478477
List<String> nbrSymbols = new ArrayList<>();
479478
Set<Sgroup> todelete = new HashSet<>();
480-
for (Sgroup sgroup : sgroupAdjs.get(attach)) {
479+
for (Sgroup sgroup : sgroupAdjs.getOrDefault(attach, Collections.emptyList())) {
481480
if (containsChargeChar(sgroup.getSubscript()))
482481
continue;
483482
if (sgroup.getBonds().size() != 1)

base/core/src/main/java/org/openscience/cdk/graph/InitialCycles.java

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@
2323
*/
2424
package org.openscience.cdk.graph;
2525

26-
import com.google.common.collect.Multimap;
27-
import com.google.common.collect.TreeMultimap;
28-
2926
import java.util.BitSet;
3027
import java.util.Collection;
28+
import java.util.Collections;
3129
import java.util.HashMap;
3230
import java.util.Map;
3331
import java.util.Objects;
32+
import java.util.Set;
33+
import java.util.TreeMap;
34+
import java.util.TreeSet;
3435

3536
import static java.util.Arrays.copyOf;
3637

@@ -54,7 +55,7 @@ final class InitialCycles {
5455
private final int[] ordering;
5556

5657
/** Cycle prototypes indexed by their length. */
57-
private final Multimap<Integer, Cycle> cycles = TreeMultimap.create();
58+
private final Map<Integer, Set<Cycle>> cycles = new TreeMap<>();
5859

5960
/** Index of edges in the graph */
6061
private final Map<Edge, Integer> edgeToIndex;
@@ -169,7 +170,7 @@ Iterable<Integer> lengths() {
169170
* @see #lengths()
170171
*/
171172
Collection<Cycle> cyclesOfLength(int length) {
172-
return cycles.get(length);
173+
return Collections.unmodifiableSet(cycles.getOrDefault(length, Collections.emptySet()));
173174
}
174175

175176
/**
@@ -178,7 +179,10 @@ Collection<Cycle> cyclesOfLength(int length) {
178179
* @return list of cycles
179180
*/
180181
Collection<Cycle> cycles() {
181-
return cycles.values();
182+
Set<Cycle> res = new TreeSet<>();
183+
for (Set<Cycle> val : cycles.values())
184+
res.addAll(val);
185+
return Collections.unmodifiableSet(res);
182186
}
183187

184188
/**
@@ -187,7 +191,10 @@ Collection<Cycle> cycles() {
187191
* @return number of cycles
188192
*/
189193
int numberOfCycles() {
190-
return cycles.size();
194+
int count = 0;
195+
for (Set<Cycle> val : cycles.values())
196+
count += val.size();
197+
return count;
191198
}
192199

193200
/**
@@ -363,7 +370,9 @@ else if (distToZ == distToY && ordering[z] < ordering[y]) {
363370
* @param cycle the cycle to add
364371
*/
365372
private void add(Cycle cycle) {
366-
if (cycle.length() <= limit) cycles.put(cycle.length(), cycle);
373+
if (cycle.length() <= limit)
374+
cycles.computeIfAbsent(cycle.length(), k -> new TreeSet<>())
375+
.add(cycle);
367376
}
368377

369378
/**
@@ -545,14 +554,15 @@ int length() {
545554

546555
@Override
547556
public int compareTo(Cycle that) {
548-
int len = Math.min(this.path.length, that.path.length);
549-
for (int i = 0; i < len; i++) {
550-
int result = Integer.compare(this.path[i], that.path[i]);
551-
if (result != 0) {
552-
return result;
553-
}
557+
int cmp = this.path.length - that.path.length;
558+
if (cmp != 0)
559+
return cmp;
560+
for (int i = 0; i < this.path.length; i++) {
561+
cmp = Integer.compare(this.path[i], that.path[i]);
562+
if (cmp != 0)
563+
return cmp;
554564
}
555-
return this.path.length - that.path.length;
565+
return 0;
556566
}
557567
}
558568

base/isomorphism/src/main/java/org/openscience/cdk/isomorphism/AtomMapFilter.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,14 @@
2323

2424
package org.openscience.cdk.isomorphism;
2525

26-
import com.google.common.collect.ArrayListMultimap;
27-
import com.google.common.collect.Multimap;
2826
import org.openscience.cdk.CDKConstants;
2927
import org.openscience.cdk.ReactionRole;
3028
import org.openscience.cdk.interfaces.IAtom;
3129
import org.openscience.cdk.interfaces.IAtomContainer;
3230

3331
import java.util.ArrayList;
3432
import java.util.Arrays;
35-
import java.util.Collection;
33+
import java.util.HashMap;
3634
import java.util.HashSet;
3735
import java.util.List;
3836
import java.util.Map;
@@ -72,8 +70,8 @@ final class AtomMapFilter implements Predicate<int[]> {
7270

7371
AtomMapFilter(IAtomContainer query, IAtomContainer target) {
7472

75-
Multimap<Integer,Integer> reactInvMap = null;
76-
Multimap<Integer,Integer> prodInvMap = null;
73+
Map<Integer,List<Integer>> reactInvMap = null;
74+
Map<Integer,List<Integer>> prodInvMap = null;
7775

7876
this.target = target;
7977

@@ -85,20 +83,20 @@ final class AtomMapFilter implements Predicate<int[]> {
8583
if (mapidx == 0) continue;
8684
switch (role(atom)) {
8785
case Reactant:
88-
if (reactInvMap == null) reactInvMap = ArrayListMultimap.create();
89-
reactInvMap.put(mapidx, idx);
86+
if (reactInvMap == null) reactInvMap = new HashMap<>();
87+
reactInvMap.computeIfAbsent(mapidx, k -> new ArrayList<>()).add(idx);
9088
break;
9189
case Product:
92-
if (prodInvMap == null) prodInvMap = ArrayListMultimap.create();
93-
prodInvMap.put(mapidx, idx);
90+
if (prodInvMap == null) prodInvMap = new HashMap<>();
91+
prodInvMap.computeIfAbsent(mapidx, k -> new ArrayList<>()).add(idx);
9492
break;
9593
}
9694
}
9795

9896
if (reactInvMap != null && prodInvMap != null) {
99-
for (Map.Entry<Integer, Collection<Integer>> e : reactInvMap.asMap().entrySet()) {
97+
for (Map.Entry<Integer, List<Integer>> e : reactInvMap.entrySet()) {
10098
int[] reacMaps = e.getValue().stream().mapToInt(i->i).toArray();
101-
int[] prodMaps = prodInvMap.get(e.getKey()).stream().mapToInt(i->i).toArray();
99+
int[] prodMaps = prodInvMap.getOrDefault(e.getKey(), new ArrayList<>()).stream().mapToInt(i->i).toArray();
102100
if (prodMaps.length == 0)
103101
continue; // unpaired
104102
mapped.add(new MappedPairs(reacMaps, prodMaps));

display/renderbasic/src/main/java/org/openscience/cdk/renderer/generators/standard/StandardSgroupGenerator.java

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323

2424
package org.openscience.cdk.renderer.generators.standard;
2525

26-
import com.google.common.collect.HashMultimap;
27-
import com.google.common.collect.Multimap;
2826
import org.openscience.cdk.CDKConstants;
2927
import org.openscience.cdk.geometry.GeometryUtil;
3028
import org.openscience.cdk.interfaces.IAtom;
@@ -78,8 +76,8 @@ final class StandardSgroupGenerator {
7876
private final double labelScale;
7977
private final StandardAtomGenerator atomGenerator;
8078
private final RendererModel parameters;
81-
private final Multimap<Sgroup,Sgroup> children = HashMultimap.create();
82-
private final Map<Sgroup,Bounds> boundsMap = new HashMap<>();
79+
private final Map<Sgroup,List<Sgroup>> children = new HashMap<>();
80+
private final Map<Sgroup,Bounds> boundsMap = new HashMap<>();
8381

8482
private StandardSgroupGenerator(RendererModel parameters, StandardAtomGenerator atomGenerator, double stroke,
8583
Font font, Color foreground) {
@@ -283,9 +281,9 @@ private static void contractAbbreviation(IAtomContainer container, Map<IAtom, St
283281
}
284282
}
285283

286-
int getTotalChildCount(Multimap<Sgroup,Sgroup> map, Sgroup key) {
284+
int getTotalChildCount(Map<Sgroup,List<Sgroup>> map, Sgroup key) {
287285
int count = 0;
288-
Deque<Sgroup> deque = new ArrayDeque<>(map.get(key));
286+
Deque<Sgroup> deque = new ArrayDeque<>(map.getOrDefault(key, Collections.emptyList()));
289287
while (!deque.isEmpty()) {
290288
Sgroup sgroup = deque.poll();
291289
deque.addAll(map.get(sgroup));
@@ -315,7 +313,7 @@ IRenderingElement generateSgroups(IAtomContainer container, AtomSymbol[] symbols
315313
}
316314
for (Sgroup sgroup : sgroups) {
317315
for (Sgroup parent : sgroup.getParents()) {
318-
children.put(parent, sgroup);
316+
children.computeIfAbsent(parent, k -> new ArrayList<>()).add(sgroup);
319317
}
320318
}
321319

@@ -815,7 +813,7 @@ else if (brackets.size() == 2) {
815813
bounds.add(atom.getPoint2d().x, atom.getPoint2d().y);
816814
}
817815
}
818-
for (Sgroup child : children.get(sgroup)) {
816+
for (Sgroup child : children.getOrDefault(sgroup, Collections.emptyList())) {
819817
Bounds childBounds = boundsMap.get(child);
820818
if (childBounds != null)
821819
bounds.add(childBounds);

legacy/src/main/java/org/openscience/cdk/smiles/smarts/SmartsAtomAtomMapFilter.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,14 @@
2323

2424
package org.openscience.cdk.smiles.smarts;
2525

26-
import com.google.common.collect.ArrayListMultimap;
27-
import com.google.common.collect.Multimap;
2826
import org.openscience.cdk.CDKConstants;
2927
import org.openscience.cdk.ReactionRole;
3028
import org.openscience.cdk.interfaces.IAtom;
3129
import org.openscience.cdk.interfaces.IAtomContainer;
3230

3331
import java.util.ArrayList;
3432
import java.util.Arrays;
35-
import java.util.Collection;
33+
import java.util.HashMap;
3634
import java.util.HashSet;
3735
import java.util.List;
3836
import java.util.Map;
@@ -73,8 +71,8 @@ final class SmartsAtomAtomMapFilter implements Predicate<int[]> {
7371

7472
SmartsAtomAtomMapFilter(IAtomContainer query, IAtomContainer target) {
7573

76-
Multimap<Integer,Integer> reactInvMap = null;
77-
Multimap<Integer,Integer> prodInvMap = null;
74+
Map<Integer,List<Integer>> reactInvMap = null;
75+
Map<Integer,List<Integer>> prodInvMap = null;
7876

7977
this.target = target;
8078

@@ -86,18 +84,18 @@ final class SmartsAtomAtomMapFilter implements Predicate<int[]> {
8684
if (mapidx == 0) continue;
8785
switch (role(atom)) {
8886
case Reactant:
89-
if (reactInvMap == null) reactInvMap = ArrayListMultimap.create();
90-
reactInvMap.put(mapidx, idx);
87+
if (reactInvMap == null) reactInvMap = new HashMap<>();
88+
reactInvMap.computeIfAbsent(mapidx, k -> new ArrayList<>()).add(idx);
9189
break;
9290
case Product:
93-
if (prodInvMap == null) prodInvMap = ArrayListMultimap.create();
94-
prodInvMap.put(mapidx, idx);
91+
if (prodInvMap == null) prodInvMap = new HashMap<>();
92+
prodInvMap.computeIfAbsent(mapidx, k -> new ArrayList<>()).add(idx);
9593
break;
9694
}
9795
}
9896

9997
if (reactInvMap != null && prodInvMap != null) {
100-
for (Map.Entry<Integer, Collection<Integer>> e : reactInvMap.asMap().entrySet()) {
98+
for (Map.Entry<Integer, List<Integer>> e : reactInvMap.entrySet()) {
10199
int[] reacMaps = e.getValue().stream().mapToInt(i->i).toArray();
102100
int[] prodMaps = prodInvMap.get(e.getKey()).stream().mapToInt(i->i).toArray();
103101
if (prodMaps.length == 0)

storage/smiles/src/main/java/org/openscience/cdk/smiles/SmilesParser.java

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
*/
2424
package org.openscience.cdk.smiles;
2525

26-
import com.google.common.collect.HashMultimap;
27-
import com.google.common.collect.Multimap;
2826
import org.openscience.cdk.CDKConstants;
2927
import org.openscience.cdk.exception.InvalidSmilesException;
3028
import org.openscience.cdk.graph.ConnectivityChecker;
@@ -570,7 +568,7 @@ else if (val.startsWith("_AP")) // attachment point
570568
}
571569
}
572570

573-
Multimap<IAtomContainer, Sgroup> sgroupMap = HashMultimap.create();
571+
Map<IAtomContainer, List<Sgroup>> sgroupMap = new HashMap<>();
574572
Map<CxSmilesState.CxSgroup, Sgroup> sgroupRemap = new HashMap<>();
575573

576574
// positional-variation
@@ -587,7 +585,8 @@ else if (val.startsWith("_AP")) // attachment point
587585
sgroup.addBond(bonds.get(0));
588586
for (Integer endpt : e.getValue())
589587
sgroup.addAtom(atoms.get(endpt));
590-
sgroupMap.put(mol, sgroup);
588+
sgroupMap.computeIfAbsent(mol, k -> new ArrayList<>())
589+
.add(sgroup);
591590
}
592591
}
593592

@@ -610,7 +609,8 @@ else if (val.startsWith("_AP")) // attachment point
610609
throw new InvalidSmilesException("CXSMILES LO: defined ordering to non-existant bond");
611610
sgroup.addBond(bond);
612611
}
613-
sgroupMap.put(mol, sgroup);
612+
sgroupMap.computeIfAbsent(mol, k -> new ArrayList<>())
613+
.add(sgroup);
614614
}
615615
}
616616

@@ -705,7 +705,8 @@ else if (amol != mol)
705705
break;
706706
}
707707

708-
sgroupMap.put(mol, sgroup);
708+
sgroupMap.computeIfAbsent(mol, k -> new ArrayList<>())
709+
.add(sgroup);
709710
// CxState Sgroup => CDK Sgroup lookup
710711
sgroupRemap.put(psgroup, sgroup);
711712
}
@@ -748,9 +749,11 @@ else if (amol != mol)
748749
cdkSgroup.putValue(SgroupKey.Data, dsgroup.value);
749750
sgroupRemap.put(dsgroup, cdkSgroup);
750751
if (mol != null)
751-
sgroupMap.put(mol, cdkSgroup);
752+
sgroupMap.computeIfAbsent(mol, k -> new ArrayList<>())
753+
.add(cdkSgroup);
752754
else if (chemObj instanceof IAtomContainer)
753-
sgroupMap.put((IAtomContainer) chemObj, cdkSgroup);
755+
sgroupMap.computeIfAbsent((IAtomContainer) chemObj, k -> new ArrayList<>())
756+
.add(cdkSgroup);
754757
}
755758
}
756759
}
@@ -806,7 +809,7 @@ else if (chemObj instanceof IAtomContainer)
806809
}
807810

808811
// assign Sgroups
809-
for (Map.Entry<IAtomContainer, Collection<Sgroup>> e : sgroupMap.asMap().entrySet())
812+
for (Map.Entry<IAtomContainer, List<Sgroup>> e : sgroupMap.entrySet())
810813
e.getKey().setProperty(CDKConstants.CTAB_SGROUPS, new ArrayList<>(e.getValue()));
811814
}
812815

0 commit comments

Comments
 (0)