diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/lda/DTMAnalyzer.java b/vipra-cmd/src/main/java/de/vipra/cmd/lda/DTMAnalyzer.java index be8d1af83be6fc039cf609ec8415fc7cad9f1d25..ac283617c19725a60740dc698133b284cd4df327 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/lda/DTMAnalyzer.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/lda/DTMAnalyzer.java @@ -9,7 +9,10 @@ import java.text.ParseException; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -23,12 +26,14 @@ import de.vipra.cmd.file.DTMVocabulary; import de.vipra.cmd.file.FilebaseIndex; import de.vipra.util.Config; import de.vipra.util.Constants; +import de.vipra.util.CountMap; import de.vipra.util.FileUtils; import de.vipra.util.StringUtils; import de.vipra.util.ex.ConfigException; import de.vipra.util.ex.DatabaseException; import de.vipra.util.model.ArticleFull; import de.vipra.util.model.Sequence; +import de.vipra.util.model.Topic; import de.vipra.util.model.TopicFull; import de.vipra.util.model.TopicRef; import de.vipra.util.model.TopicWord; @@ -161,47 +166,76 @@ public class DTMAnalyzer extends Analyzer { // read topic definition files and create topics + Map<Word, Topic> topicWordMap = new HashMap<>(vocab.size()); List<TopicFull> newTopics = new ArrayList<>(Constants.K_TOPICS); List<Word> newWords = new ArrayList<>(vocab.size()); int sequencesCount = sequences.size(); - // for each topic + // for each topic file for (int i = 0; i < Constants.K_TOPICS; i++) { File seqFile = new File(outDirSeq, "topic-" + StringUtils.padNumber(i, 3) + "-var-e-log-prob.dat"); int lineCount = FileUtils.countLines(seqFile); - int wordsPerSequence = lineCount / sequencesCount; + int wordsCount = lineCount / sequencesCount; - if (wordsPerSequence * sequencesCount != lineCount) { + if (wordsCount * sequencesCount != lineCount) { log.error("unexpected number of words per sequence"); continue; } + // create new topic + TopicFull newTopic = new TopicFull(); + List<Sequence> newSequences = new ArrayList<>(sequencesCount); + List<TopicWord> newTopicWords = new ArrayList<>(wordsCount); + newTopic.setSequences(newSequences); + newTopic.setWords(newTopicWords); + newTopics.add(newTopic); + in = new BufferedReader(new InputStreamReader(new FileInputStream(seqFile))); // read file lines into word x sequence matrix - // gather maximum likeliness per sequence - double[] maxLikelinesses = new double[sequencesCount]; - double[][] likelinesses = new double[wordsPerSequence][sequencesCount]; - for (int idxWord = 0; idxWord < wordsPerSequence; idxWord++) { + // gather maximum likeliness per sequence and per word + double[] maxSeqLikelinesses = new double[sequencesCount]; + double[] maxWordLikelinesses = new double[wordsCount]; + double[][] likelinesses = new double[wordsCount][sequencesCount]; + for (int idxWord = 0; idxWord < wordsCount; idxWord++) { for (int idxSeq = 0; idxSeq < sequencesCount; idxSeq++) { double likeliness = Double.parseDouble(in.readLine()); likelinesses[idxWord][idxSeq] = likeliness; - if (likeliness > maxLikelinesses[idxSeq]) - maxLikelinesses[idxSeq] = likeliness; + if (likeliness > maxSeqLikelinesses[idxSeq]) + maxSeqLikelinesses[idxSeq] = likeliness; + if (likeliness > maxWordLikelinesses[idxWord]) + maxWordLikelinesses[idxWord] = likeliness; } } in.close(); - List<Sequence> newSequences = new ArrayList<>(sequencesCount); + // find maximum overall likeliness + double maxOverallLikeliness = 0; + for (double likeliness : maxSeqLikelinesses) { + if (likeliness > maxOverallLikeliness) + maxOverallLikeliness = likeliness; + } + // static topic + // most likely words form the static topic over all sequences + for (int idxWord = 0; idxWord < wordsCount; idxWord++) { + if (maxWordLikelinesses[idxWord] >= Constants.MINIMUM_RELATIVE_PROB * maxOverallLikeliness) { + Word newWord = new Word(vocab.get(idxWord)); + newWords.add(newWord); + TopicWord newTopicWord = new TopicWord(newWord, maxWordLikelinesses[idxWord]); + newTopicWords.add(newTopicWord); + } + } + + // dynamic topics // go through each sequence and gather all words that are above // the minimum relative word likeliness for (int idxSeq = 0; idxSeq < sequencesCount; idxSeq++) { - double maxLikeliness = maxLikelinesses[idxSeq]; - List<TopicWord> newSeqTopicWords = new ArrayList<>(wordsPerSequence); - for (int idxWord = 0; idxWord < wordsPerSequence; idxWord++) { + double maxLikeliness = maxSeqLikelinesses[idxSeq]; + List<TopicWord> newSeqTopicWords = new ArrayList<>(wordsCount); + for (int idxWord = 0; idxWord < wordsCount; idxWord++) { double likeliness = likelinesses[idxWord][idxSeq]; if (likeliness >= Constants.MINIMUM_RELATIVE_PROB * maxLikeliness) { Word newWord = new Word(vocab.get(idxWord)); @@ -216,15 +250,7 @@ public class DTMAnalyzer extends Analyzer { newSequence.setNumber(idxSeq); newSequence.setWords(newSeqTopicWords); newSequences.add(newSequence); - - // TODO gather words for static topic } - - TopicFull newTopic = new TopicFull(); - newTopic.setSequences(newSequences); - newTopics.add(newTopic); - - // TODO add words to static topic } // recreate topics and words @@ -246,17 +272,39 @@ public class DTMAnalyzer extends Analyzer { // for each article in the model file while ((line = in.readLine()) != null) { - List<TopicRef> newTopicRefs = new ArrayList<>(); - - // extract word:count pairs + // extract unique word ids and count + CountMap<Integer> countMap = new CountMap<>(); Matcher matcher = wordCountPattern.matcher(line); + double totalCount = 0; while (matcher.find()) { - int idxWord = Integer.parseInt(matcher.group(1)); - int wordCount = Integer.parseInt(matcher.group(2)); + int count = Integer.parseInt(matcher.group(2)); + countMap.count(Integer.parseInt(matcher.group(1)), count); + totalCount += count; + } - // TODO find topic/s of word, add as reference/s + // create list of topics refs referencing topics with counted + // occurrences, sum accepted topic word count + long reducedCount = 0; + List<TopicRef> newTopicRefs = new ArrayList<>(countMap.size()); + for (Entry<Integer, Integer> entry : countMap.entrySet()) { + // check if topic above threshold + if ((entry.getValue() / totalCount) >= Constants.TOPIC_THRESHOLD) { + reducedCount += entry.getValue(); + TopicFull topic = null; + // TODO find topic of this word + if (topic != null) { + TopicRef ref = new TopicRef(); + ref.setCount(entry.getValue()); + ref.setTopic(new Topic(topic.getId())); + newTopicRefs.add(ref); + } + } } + // calculate each accepted topic share + for (TopicRef ref : newTopicRefs) + ref.setShare((double) ref.getCount() / reducedCount); + if (!newTopicRefs.isEmpty()) { Collections.sort(newTopicRefs, Comparator.reverseOrder()); @@ -274,7 +322,7 @@ public class DTMAnalyzer extends Analyzer { } } - // TODO create topic references + in.close(); } catch (IOException | InterruptedException e) { throw new AnalyzerException(e); diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/lda/JGibbAnalyzer.java b/vipra-cmd/src/main/java/de/vipra/cmd/lda/JGibbAnalyzer.java index 80961888bc499d5b82a86a813125a37a6cf21b4e..ce3b4adb9dac71f4e4ee2aecccfed4403791fa8b 100644 --- a/vipra-cmd/src/main/java/de/vipra/cmd/lda/JGibbAnalyzer.java +++ b/vipra-cmd/src/main/java/de/vipra/cmd/lda/JGibbAnalyzer.java @@ -202,6 +202,10 @@ public class JGibbAnalyzer extends Analyzer { if ((entry.getValue() / totalCount) >= Constants.TOPIC_THRESHOLD) { reducedCount += entry.getValue(); TopicFull topic = newTopics.get(Integer.parseInt(entry.getKey())); + // TODO words with low relative likeliness are ignored. + // topic references from this file are possibly wrong. + // fix this by checking if the word is actually accepted + // by the referenced topic. TopicRef ref = new TopicRef(); ref.setCount(entry.getValue()); ref.setTopic(new Topic(topic.getId())); @@ -229,7 +233,9 @@ public class JGibbAnalyzer extends Analyzer { } } } + in.close(); + } catch (IOException e) { throw new AnalyzerException(e); } diff --git a/vipra-ui/.gitignore b/vipra-ui/.gitignore index d7dfae0cdc09270d342c3aabbb6f1bd8b6c2050c..ea0841a79735bf02b4ce279fbd0aa26a4314e835 100644 --- a/vipra-ui/.gitignore +++ b/vipra-ui/.gitignore @@ -1,3 +1,3 @@ -node_modules/ -bower_components/ -public/ \ No newline at end of file +/node_modules/ +/bower_components/ +/public/ diff --git a/vipra-ui/app/public/android-chrome-144x144.png b/vipra-ui/app/public/android-chrome-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..65381273deb698c342f41b64eb893d20213ef277 Binary files /dev/null and b/vipra-ui/app/public/android-chrome-144x144.png differ diff --git a/vipra-ui/app/public/android-chrome-192x192.png b/vipra-ui/app/public/android-chrome-192x192.png new file mode 100644 index 0000000000000000000000000000000000000000..aafb35c9c7aa01012b001a1f7836853438499468 Binary files /dev/null and b/vipra-ui/app/public/android-chrome-192x192.png differ diff --git a/vipra-ui/app/public/android-chrome-36x36.png b/vipra-ui/app/public/android-chrome-36x36.png new file mode 100644 index 0000000000000000000000000000000000000000..6bce0e7b3b45c597b9f204dd858bbf5c712d4d1e Binary files /dev/null and b/vipra-ui/app/public/android-chrome-36x36.png differ diff --git a/vipra-ui/app/public/android-chrome-48x48.png b/vipra-ui/app/public/android-chrome-48x48.png new file mode 100644 index 0000000000000000000000000000000000000000..2a39ff69671c5ba5fb84f59dae8349798b6aad17 Binary files /dev/null and b/vipra-ui/app/public/android-chrome-48x48.png differ diff --git a/vipra-ui/app/public/android-chrome-72x72.png b/vipra-ui/app/public/android-chrome-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..a7ade354c62c1dd8a022c4e0134f809cd9515ed9 Binary files /dev/null and b/vipra-ui/app/public/android-chrome-72x72.png differ diff --git a/vipra-ui/app/public/android-chrome-96x96.png b/vipra-ui/app/public/android-chrome-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..cc8c4f026464b8f964d934e6a075fe4335c529ef Binary files /dev/null and b/vipra-ui/app/public/android-chrome-96x96.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-114x114.png b/vipra-ui/app/public/apple-touch-icon-114x114.png new file mode 100644 index 0000000000000000000000000000000000000000..26b8a7d69827310482e81808a72d3efbba60b56e Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-114x114.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-120x120.png b/vipra-ui/app/public/apple-touch-icon-120x120.png new file mode 100644 index 0000000000000000000000000000000000000000..c18a4b0c4165d83437effce47e4f9ad792ef7b2c Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-120x120.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-144x144.png b/vipra-ui/app/public/apple-touch-icon-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..ef1fa16a3a67355ba5a7276968b0a30c9e20cb83 Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-144x144.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-152x152.png b/vipra-ui/app/public/apple-touch-icon-152x152.png new file mode 100644 index 0000000000000000000000000000000000000000..9fba2775b8a68a5c1ecbca39b1b6fdf14a2154f9 Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-152x152.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-180x180.png b/vipra-ui/app/public/apple-touch-icon-180x180.png new file mode 100644 index 0000000000000000000000000000000000000000..0180434fdf49860cba267885d4dcea5e30cf6efe Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-180x180.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-57x57.png b/vipra-ui/app/public/apple-touch-icon-57x57.png new file mode 100644 index 0000000000000000000000000000000000000000..10a252a1ea5bd34a1abed6da4ca0984651683cd8 Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-57x57.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-60x60.png b/vipra-ui/app/public/apple-touch-icon-60x60.png new file mode 100644 index 0000000000000000000000000000000000000000..6768760fbb6a0d7c028044d7e122706d3e5593ee Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-60x60.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-72x72.png b/vipra-ui/app/public/apple-touch-icon-72x72.png new file mode 100644 index 0000000000000000000000000000000000000000..76be1bfbff4558a65521ce41425adc24c34cd480 Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-72x72.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-76x76.png b/vipra-ui/app/public/apple-touch-icon-76x76.png new file mode 100644 index 0000000000000000000000000000000000000000..a8f6f0838af09eeb236b7214af203d0345f72262 Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-76x76.png differ diff --git a/vipra-ui/app/public/apple-touch-icon-precomposed.png b/vipra-ui/app/public/apple-touch-icon-precomposed.png new file mode 100644 index 0000000000000000000000000000000000000000..53e37b390437c21e75ac1b3139c159e9b8eaf7d7 Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon-precomposed.png differ diff --git a/vipra-ui/app/public/apple-touch-icon.png b/vipra-ui/app/public/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..0180434fdf49860cba267885d4dcea5e30cf6efe Binary files /dev/null and b/vipra-ui/app/public/apple-touch-icon.png differ diff --git a/vipra-ui/app/public/browserconfig.xml b/vipra-ui/app/public/browserconfig.xml new file mode 100644 index 0000000000000000000000000000000000000000..65380f3873df0b1efc837c390c3a91bd2c2c6a14 --- /dev/null +++ b/vipra-ui/app/public/browserconfig.xml @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="utf-8"?> +<browserconfig> + <msapplication> + <tile> + <square70x70logo src="/mstile-70x70.png"/> + <square150x150logo src="/mstile-150x150.png"/> + <square310x310logo src="/mstile-310x310.png"/> + <wide310x150logo src="/mstile-310x150.png"/> + <TileColor>#da532c</TileColor> + </tile> + </msapplication> +</browserconfig> diff --git a/vipra-ui/app/public/favicon-16x16.png b/vipra-ui/app/public/favicon-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..cf3c09a89bc2eb35efc55ab635a533c04e598d72 Binary files /dev/null and b/vipra-ui/app/public/favicon-16x16.png differ diff --git a/vipra-ui/app/public/favicon-32x32.png b/vipra-ui/app/public/favicon-32x32.png new file mode 100644 index 0000000000000000000000000000000000000000..dadf3b2e6f39e46f25180ebf233dac0e595a5794 Binary files /dev/null and b/vipra-ui/app/public/favicon-32x32.png differ diff --git a/vipra-ui/app/public/favicon-96x96.png b/vipra-ui/app/public/favicon-96x96.png new file mode 100644 index 0000000000000000000000000000000000000000..817d8a24219728859aa5cc5e634c092270e18b4b Binary files /dev/null and b/vipra-ui/app/public/favicon-96x96.png differ diff --git a/vipra-ui/app/public/favicon.ico b/vipra-ui/app/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..6444887cb42005b7163bb67e6ad9750e6a2bd8bf Binary files /dev/null and b/vipra-ui/app/public/favicon.ico differ diff --git a/vipra-ui/app/public/manifest.json b/vipra-ui/app/public/manifest.json new file mode 100644 index 0000000000000000000000000000000000000000..fd248ba860774e85815f340dca3d7a91b00fc794 --- /dev/null +++ b/vipra-ui/app/public/manifest.json @@ -0,0 +1,41 @@ +{ + "name": "Vipra", + "icons": [ + { + "src": "\/android-chrome-36x36.png", + "sizes": "36x36", + "type": "image\/png", + "density": 0.75 + }, + { + "src": "\/android-chrome-48x48.png", + "sizes": "48x48", + "type": "image\/png", + "density": 1 + }, + { + "src": "\/android-chrome-72x72.png", + "sizes": "72x72", + "type": "image\/png", + "density": 1.5 + }, + { + "src": "\/android-chrome-96x96.png", + "sizes": "96x96", + "type": "image\/png", + "density": 2 + }, + { + "src": "\/android-chrome-144x144.png", + "sizes": "144x144", + "type": "image\/png", + "density": 3 + }, + { + "src": "\/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image\/png", + "density": 4 + } + ] +} diff --git a/vipra-ui/app/public/mstile-144x144.png b/vipra-ui/app/public/mstile-144x144.png new file mode 100644 index 0000000000000000000000000000000000000000..89b398770272b9c12ac16f5c810e542f10497e76 Binary files /dev/null and b/vipra-ui/app/public/mstile-144x144.png differ diff --git a/vipra-ui/app/public/mstile-150x150.png b/vipra-ui/app/public/mstile-150x150.png new file mode 100644 index 0000000000000000000000000000000000000000..dc068265457b54bdb8ac5f010aa2eb96ef6a1618 Binary files /dev/null and b/vipra-ui/app/public/mstile-150x150.png differ diff --git a/vipra-ui/app/public/mstile-310x150.png b/vipra-ui/app/public/mstile-310x150.png new file mode 100644 index 0000000000000000000000000000000000000000..b08a4626d1b93684f5bda1877a6e8ef6cdbfbf58 Binary files /dev/null and b/vipra-ui/app/public/mstile-310x150.png differ diff --git a/vipra-ui/app/public/mstile-310x310.png b/vipra-ui/app/public/mstile-310x310.png new file mode 100644 index 0000000000000000000000000000000000000000..e8b6d0106eaa4419b218d40941384d89df500ed6 Binary files /dev/null and b/vipra-ui/app/public/mstile-310x310.png differ diff --git a/vipra-ui/app/public/mstile-70x70.png b/vipra-ui/app/public/mstile-70x70.png new file mode 100644 index 0000000000000000000000000000000000000000..35d39ae9f74b519b9385484ce26fa9e6fe46d291 Binary files /dev/null and b/vipra-ui/app/public/mstile-70x70.png differ diff --git a/vipra-ui/app/public/safari-pinned-tab.svg b/vipra-ui/app/public/safari-pinned-tab.svg new file mode 100644 index 0000000000000000000000000000000000000000..e8228a317e06bbb96fe61b8f8273f7bd20214b22 --- /dev/null +++ b/vipra-ui/app/public/safari-pinned-tab.svg @@ -0,0 +1,37 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" + "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"> +<svg version="1.0" xmlns="http://www.w3.org/2000/svg" + width="1000.000000pt" height="1000.000000pt" viewBox="0 0 1000.000000 1000.000000" + preserveAspectRatio="xMidYMid meet"> +<metadata> +Created by potrace 1.11, written by Peter Selinger 2001-2013 +</metadata> +<g transform="translate(0.000000,1000.000000) scale(0.100000,-0.100000)" +fill="#000000" stroke="none"> +<path d="M9935 8020 c-33 -15 -217 -101 -410 -190 -192 -89 -392 -182 -444 +-206 -51 -24 -95 -44 -96 -44 -2 0 -60 -27 -130 -60 -70 -33 -128 -60 -130 +-60 -2 0 -46 -20 -97 -44 -51 -24 -118 -55 -148 -69 -67 -31 -578 -267 -675 +-312 -38 -18 -272 -126 -520 -240 -548 -253 -534 -246 -674 -312 -62 -29 -115 +-53 -117 -53 -2 0 -60 -27 -130 -60 -69 -33 -128 -60 -130 -60 -2 0 -60 -27 +-130 -60 -69 -33 -128 -60 -129 -60 -2 0 -39 -16 -82 -36 -143 -67 -217 -101 +-298 -139 -44 -20 -163 -75 -265 -122 -102 -47 -217 -100 -257 -119 l-72 -33 +-813 375 c-919 425 -847 391 -1113 514 -110 50 -242 112 -294 136 -51 24 -95 +44 -97 44 -2 0 -45 20 -96 44 -51 24 -120 56 -153 71 -96 44 -175 80 -245 113 +-78 36 -442 204 -520 240 -30 13 -118 54 -195 89 -77 36 -187 87 -245 113 -58 +26 -143 66 -190 88 -47 22 -139 64 -205 95 -66 30 -149 68 -185 85 -306 142 +-634 291 -636 289 -2 -2 87 -113 197 -247 448 -547 1051 -1282 1154 -1410 61 +-74 120 -146 132 -160 80 -96 137 -165 188 -230 33 -41 62 -77 65 -80 3 -3 77 +-93 165 -200 88 -107 162 -197 165 -200 3 -3 43 -52 90 -110 47 -58 92 -114 +102 -125 15 -18 238 -290 516 -630 63 -77 130 -158 148 -180 18 -22 121 -148 +229 -280 108 -132 219 -267 247 -300 27 -33 55 -67 61 -75 39 -48 252 -309 +270 -330 12 -14 40 -47 61 -75 22 -27 48 -58 57 -70 19 -22 131 -158 488 -594 +128 -157 247 -302 263 -321 16 -19 109 -133 206 -252 l177 -217 21 22 c12 12 +188 225 390 472 432 527 822 1003 869 1060 18 22 234 285 479 585 246 300 462 +563 480 585 19 22 210 256 426 520 216 264 414 505 439 535 26 30 73 89 106 +130 33 41 63 77 66 80 4 3 32 37 63 75 70 87 43 53 290 355 115 140 225 275 +246 300 21 25 104 126 185 225 81 99 162 198 181 220 18 22 90 110 159 195 70 +85 134 164 143 175 10 11 89 108 176 215 139 169 217 265 274 333 18 21 20 21 +-53 -13z"/> +</g> +</svg> diff --git a/vipra-util/src/main/java/de/vipra/util/CountMap.java b/vipra-util/src/main/java/de/vipra/util/CountMap.java index 5200660a23060c128034cf54373cc25244586be0..bdb9af1e5bee624dfd3cd87de7b2c0cef28d11e9 100644 --- a/vipra-util/src/main/java/de/vipra/util/CountMap.java +++ b/vipra-util/src/main/java/de/vipra/util/CountMap.java @@ -18,11 +18,15 @@ public class CountMap<T> { } public void count(T t) { + count(t, 1); + } + + public void count(T t, int add) { Integer count = map.get(t); if (count == null) - map.put(t, 1); + map.put(t, add); else - map.put(t, count + 1); + map.put(t, count + add); } public Set<Entry<T, Integer>> entrySet() {