{"id":641,"date":"2011-10-07T16:35:00","date_gmt":"2011-10-07T16:35:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/scala-tutorial-scala-io-source-accessing-files-flatmap-mutable-maps.html"},"modified":"2012-10-21T20:31:12","modified_gmt":"2012-10-21T20:31:12","slug":"scala-tutorial-scalaiosource-accessing","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html","title":{"rendered":"Scala Tutorial &#8211; scala.io.Source, accessing files, flatMap, mutable Maps"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\">\n<h2>     Preface<\/h2>\n<p>This is part 8 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other resources on <a href=\"http:\/\/icl-f11.utcompling.com\/links\">the links page of the Computational Linguistics course<\/a> I\u2019m creating these for. Additionally you can find this and other tutorial series on the JCG <a href=\"http:\/\/www.javacodegeeks.com\/p\/java-tutorials.html\">Java Tutorials<\/a> page.<\/p>\n<p>This tutorial is about accessing the file system in order to work with text files. The previous tutorial showed how to build a Map that contains the counts of each word type in a given text. However, it was assumed that the text was available in a String variable, and typically we are interested in knowing things about files that live on the file system, or on the internet. This tutorial shows how to read a file\u2019s contents into Scala for processing, both by building a single String for the file or by consuming it line-by-line in a streaming fashion. Along the way, immutable Maps are introduced as a way to enable word counting without reading an entire file into memory.<\/p>\n<h2>     Word count on the contents of a file<\/h2>\n<p>As an example, we\u2019ll use <a href=\"http:\/\/www.gutenberg.org\/cache\/epub\/1661\/pg1661.txt\">the complete Sherlock Holmes from project Gutenberg<\/a>. Download it, put it into a directory, and then start up the Scala REPL in that directory. To access files, we\u2019ll use the <strong>Source<\/strong> class, so to start you need to import it.<\/p>\n<pre class=\"brush: scala;\">scala&gt; import scala.io.Source\r\nimport scala.io.Source\r\n<\/pre>\n<p><strong>Source<\/strong> provides a number of ways to interact with files and make them accessible to you in your Scala program. The <strong>fromFile<\/strong> method is the one you\u2019ll probably need most.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Source.fromFile(\"pg1661.txt\")\r\nres3: scala.io.BufferedSource = non-empty iterator\r\n<\/pre>\n<p>This creates a <strong>BufferedSource<\/strong>, from which you can easily get all of file\u2019s contents as a String.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val holmes = Source.fromFile(\"pg1661.txt\").mkString\r\nholmes: String =\r\n\"Project Gutenberg's The Adventures of Sherlock Holmes, by Arthur Conan Doyle\r\n\r\nThis eBook is for the use of anyone anywhere at no cost and with\r\nalmost no restrictions whatsoever.  You may copy it, give it away or\r\nre-use it under the terms of the Project Gutenberg License included\r\nwith this eBook or online at www.gutenberg.net\r\n&lt;...many more lines...&gt;\r\n<\/pre>\n<p>With this, you can do the same things as shown it <a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-maps-sets-groupby.html\" title=\"First steps in Scala for beginning programmers, Part 7\">tutorial 7<\/a> to get the word counts (except that here we\u2019ll split on white space sequences rather than just a single space).<\/p>\n<pre class=\"brush: scala;\">scala&gt; val counts = holmes.split(\"\\\\s+\").groupBy(x=&gt;x).mapValues(x=&gt;x.length)\r\ncounts: scala.collection.immutable.Map[java.lang.String,Int] = Map(wood-work, -&gt; 1, \"Pray, -&gt; 1, herself. -&gt; 2, stern-post -&gt; 1, \"Should -&gt; 1, incident -&gt; 8, serious -&gt; 14, earth--\" -&gt; 2, sinister -&gt; 10, comply -&gt; 7, breaks -&gt; 1, forgotten -&gt; 3, precious -&gt; 10, 'It -&gt; 3, compliment -&gt; 2, suite, -&gt; 1, \"DEAR -&gt; 1, summarise. -&gt; 1, \"Done -&gt; 1, fine.' -&gt; 1, lover -&gt; 5, of. -&gt; 2, lead. -&gt; 1, plentiful -&gt; 1, 'Lone -&gt; 4, malignant -&gt; 1, terrible -&gt; 14, rate -&gt; 1, mole -&gt; 1, assert -&gt; 1, lights -&gt; 2, Stevenson, -&gt; 1, submitted -&gt; 4, tap. -&gt; 1, beard, -&gt; 1, band--a -&gt; 1, force! -&gt; 1, snow -&gt; 7, Produced -&gt; 2, ask, -&gt; 1, purchasing -&gt; 1, Hall, -&gt; 1, wall. -&gt; 5, remarked -&gt; 32, laughing -&gt; 4, member.\" -&gt; 1, 30,000 -&gt; 2, Redistributing -&gt; 1, coat, -&gt; 6, \"'One -&gt; 2, 'band,' -&gt; 1, relapsed -&gt; 1, apol...\r\n\r\nscala&gt; counts(\"Holmes\")\r\nres2: Int = 197\r\n\r\nscala&gt; counts(\"Watson\")\r\nres3: Int = 4\r\n<\/pre>\n<p>Lest you think it strange that <em>Watson<\/em> only shows up four times, keep in mind that we split on whitespace, and that means that in a sentence like the following, the token of interest is <em>Watson,\u201d<\/em> rather than <em>Watson<\/em>.<\/p>\n<div style=\"padding-left: 30px\"><em>\u201cYou could not possibly have come at a better time, my dear Watson,\u201d he said cordially.<\/em><br \/>\n<em><br \/>\n<\/em><\/div>\n<p>Looking that and others up shows more tokens containing <em>Watson<\/em> in the story.<\/p>\n<pre class=\"brush: scala;\">scala&gt; counts(\"Watson,\\\"\")\r\nres4: Int = 19\r\n\r\nscala&gt; counts(\"Watson,\")\r\nres5: Int = 40\r\n\r\nscala&gt; counts(\"Watson.\")\r\nres6: Int = 10\r\n<\/pre>\n<p>Of course, the real problem is that tokenizing on whitespace is too crude. To do this properly generally takes a good hand-built tokenizer (which is able to keep tokens like <em>e.g.<\/em> and <em>Mr.<\/em> and <em>Yahoo!<\/em> while splitting punctuation off most words) or a machine learned one that is trained on data hand-labeled for tokens. For an example of the latter, see <a href=\"http:\/\/incubator.apache.org\/opennlp\/documentation\/manual\/opennlp.html#tools.tokenizer\">the Apache OpenNLP toolkit tokenizers<\/a>, which includes pre-trained models for English.<\/p>\n<h2>     Working line by line<\/h2>\n<p>Quite often, you need to work through a file line by line, rather than reading the entire thing in as a single string as we did above. For example, you might need to process each line differently, so just having it as a single String isn\u2019t particular convenient. Or, you might be working with a large file that cannot easily fit into memory (which is what happens when you read in the entire string). You can obtain the lines in the file as an <strong>Iterator[String]<\/strong>, in which each item is a single line from the file, using the <strong>getLines<\/strong> method.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Source.fromFile(\"pg1661.txt\").getLines\r\nres4: Iterator[String] = non-empty iterator\r\n<\/pre>\n<p>This iterator is ready for you to consume lines, but it doesn\u2019t read all of the file into memory right away \u2014 instead it buffers it such that each line will be available for you as you ask for it, essentially reading off disk as you demand more lines. You can think of this as <em>streaming<\/em> the file to your Scala program, much like modern audio and video content is streamed to your computer: it is never actually stored, but is just transferred in parts to where it is needed, when it is needed.<\/p>\n<p>Of course, Iterators share much with sequence data structures like Lists: once we have an Iterator, we can use <strong>foreach<\/strong>, <strong>for<\/strong>, <strong>map<\/strong>, etc. on it. So to print out all of the lines in the file, we can do the following.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Source.fromFile(\"pg1661.txt\").getLines.foreach(println)\r\nProject Gutenberg's The Adventures of Sherlock Holmes, by Arthur Conan Doyle\r\n\r\nThis eBook is for the use of anyone anywhere at no cost and with\r\nalmost no restrictions whatsoever.  You may copy it, give it away or\r\nre-use it under the terms of the Project Gutenberg License included\r\nwith this eBook or online at www.gutenberg.net\r\n\r\nTitle: The Adventures of Sherlock Holmes\r\n\r\nAuthor: Arthur Conan Doyle\r\n&lt;...many more lines...&gt;\r\n<\/pre>\n<p>That creates a lot of output, but it shows you how you can easily create your own Scala implementation of the Unix <strong>cat<\/strong> program: just save the following line in a file called <strong>cat.scala<\/strong>:<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush: scala;\">scala.io.Source.fromFile(args(0)).getLines.foreach(println)\r\n<\/pre>\n<p>And then call that with the name of the file to list its contents.<\/p>\n<pre class=\"brush: bash;\">$ scala cat.scala pg1661.txt\r\n<\/pre>\n<p>Back in the REPL, it is somewhat less-than-ideal to see the entire file. If you just want to see the start of the file, use the <strong>take<\/strong> method on the Iterator before the <strong>foreach<\/strong>.<\/p>\n<pre class=\"brush: scala;\">scala&gt; Source.fromFile(\"pg1661.txt\").getLines.take(5).foreach(println)\r\nProject Gutenberg's The Adventures of Sherlock Holmes, by Arthur Conan Doyle\r\n\r\nThis eBook is for the use of anyone anywhere at no cost and with\r\nalmost no restrictions whatsoever.  You may copy it, give it away or\r\nre-use it under the terms of the Project Gutenberg License included\r\n<\/pre>\n<p>The <strong>take<\/strong> method is quite useful in general with any sequence, and provides the complement of the drop method, as shown in the following examples on a simple <strong>List[Int]<\/strong>.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val numbers = 1 to 10 toList\r\nnumbers: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\r\n\r\nscala&gt; numbers.take(3)\r\nres12: List[Int] = List(1, 2, 3)\r\n\r\nscala&gt; numbers.drop(3)\r\nres13: List[Int] = List(4, 5, 6, 7, 8, 9, 10)\r\n\r\nscala&gt; numbers.take(3) ::: numbers.drop(3)\r\nres14: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)\r\n<\/pre>\n<h2>     Word counting line by line, first try<\/h2>\n<p>Now that we\u2019ve seen how to read a file and start working with it line-by-line, how do we count the number of occurrences of each word? Recall from <a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-maps-sets-groupby.html\" title=\"First steps in Scala for beginning programmers, Part 7\">tutorial 7 <\/a>and above that the starting point was to have a sequence (Array, List, etc) of Strings in which each element is a word token. To start moving toward that, we can simply use the <strong>toList<\/strong> method on the <strong>Iterator[String]<\/strong> obtained from <strong>getLines<\/strong>.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val holmes = Source.fromFile(\"pg1661.txt\").getLines.toList\r\nholmes: List[String] = List(The Project Gutenberg EBook of The Adventures of Sherlock Holmes, by Sir Arthur Conan Doyle, (#15 in our series by Sir Arthur Conan Doyle), \"\", Copyright laws are changing all over the world. Be sure to check the, copyright laws for your country before downloading or redistributing, this or any other Project Gutenberg eBook., \"\", This header should be the first thing seen when viewing this Project, Gutenberg file.  Please do not remove it.  Do not change or edit the, header without written permission., \"\", Please read the \"legal small print,\" and other information about the, eBook and Project Gutenberg at the bottom of this file.  Included is, important information about your specific rights and restrictions in, how the file may be used.  You can also find ou...\r\n<\/pre>\n<p>We now have the contents of the file as a <strong>List[String]<\/strong>, and may proceed to do useful things with it. For example, we could <strong>map<\/strong> each line (Strings) to be sequences of whitespace-separated Strings.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val listOfListOfWords = Source.fromFile(\"pg1661.txt\").getLines.toList.map(x =&gt; x.split(\" \").toList)\r\nlistOfListOfWords: List[List[java.lang.String]] = List(List(Project, Gutenberg's, The, Adventures, of, Sherlock, Holmes,, by, Arthur, Conan, Doyle), List(\"\"), List(This, eBook, is, for, the, use, of, anyone, anywhere, at, no, cost, and, with), List(almost, no, restrictions, whatsoever., \"\", You, may, copy, it,, give, it, away, or), List(re-use, it, under, the, terms, of, the, Project, Gutenberg, License, included), List(with, this, eBook, or, online, at, www.gutenberg.net), List(\"\"), List(\"\"), List(Title:, The, Adventures, of, Sherlock, Holmes), List(\"\"), List(Author:, Arthur, Conan, Doyle), List(\"\"), List(Posting, Date:, April, 18,, 2011, [EBook, #1661]), List(First, Posted:, November, 29,, 2002), List(\"\"), List(Language:, English), List(\"\"), List(\"\"), List(***, START, OF, THIS, PRO...\r\n<\/pre>\n<p>And, as we saw in <a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-maps-sets-groupby.html\" title=\"First steps in Scala for beginning programmers, Part 7\">tutorial 7<\/a>, when we have a List of Lists, we can use <strong>flatten<\/strong> to create one big List.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val listOfWords = listOfListOfWords.flatten\r\nlistOfWords: List[java.lang.String] = List(Project, Gutenberg's, The, Adventures, of, Sherlock, Holmes,, by, Arthur, Conan, Doyle, \"\", This, eBook, is, for, the, use, of, anyone, anywhere, at, no, cost, and, with, almost, no, restrictions, whatsoever., \"\", You, may, copy, it,, give, it, away, or, re-use, it, under, the, terms, of, the, Project, Gutenberg, License, included, with, this, eBook, or, online, at, www.gutenberg.net, \"\", \"\", Title:, The, Adventures, of, Sherlock, Holmes, \"\", Author:, Arthur, Conan, Doyle, \"\", Posting, Date:, April, 18,, 2011, [EBook, #1661], First, Posted:, November, 29,, 2002, \"\", Language:, English, \"\", \"\", ***, START, OF, THIS, PROJECT, GUTENBERG, EBOOK, THE, ADVENTURES, OF, SHERLOCK, HOLMES, ***, \"\", \"\", \"\", \"\", Produced, by, an, anonymous, Project, Gut...\r\n<\/pre>\n<p>But, now you might recognize that this is the <em>map-then-flatten<\/em> pattern we saw previously, which means we can <strong>flatMap<\/strong> it instead.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val flatMappedWords = Source.fromFile(\"pg1661.txt\").getLines.toList.flatMap(x =&gt; x.split(\" \"))\r\nflatMappedWords: List[java.lang.String] = List(Project, Gutenberg's, The, Adventures, of, Sherlock, Holmes,, by, Arthur, Conan, Doyle, \"\", This, eBook, is, for, the, use, of, anyone, anywhere, at, no, cost, and, with, almost, no, restrictions, whatsoever., \"\", You, may, copy, it,, give, it, away, or, re-use, it, under, the, terms, of, the, Project, Gutenberg, License, included, with, this, eBook, or, online, at, www.gutenberg.net, \"\", \"\", Title:, The, Adventures, of, Sherlock, Holmes, \"\", Author:, Arthur, Conan, Doyle, \"\", Posting, Date:, April, 18,, 2011, [EBook, #1661], First, Posted:, November, 29,, 2002, \"\", Language:, English, \"\", \"\", ***, START, OF, THIS, PROJECT, GUTENBERG, EBOOK, THE, ADVENTURES, OF, SHERLOCK, HOLMES, ***, \"\", \"\", \"\", \"\", Produced, by, an, anonymous, Project,...\r\n<\/pre>\n<p>But you should be a bit bothered by all this: wasn\u2019t the idea here (in part) not to read all of the lines in at once? Indeed, with what we did above, as soon as we said <strong>toList<\/strong> on the Iterator, the whole file was read into memory. However, we can do without the <strong>toList<\/strong> step and just directly <strong>flatMap<\/strong> the Iterator and get a new Iterator over the tokens rather than the lines.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val flatMappedWords = Source.fromFile(\"pg1661.txt\").getLines.flatMap(x =&gt; x.split(\" \"))\r\nflatMappedWords: Iterator[java.lang.String] = non-empty iterator\r\n<\/pre>\n<p>Now, if we want to count the words, we can convert that to a List and do the <strong>groupBy<\/strong> the <strong>mapValues<\/strong> trick we\u2019ve seen already (output omitted).<\/p>\n<pre class=\"brush: scala;\">scala&gt; val counts = Source.fromFile(\"pg1661.txt\").getLines.flatMap(x =&gt; x.split(\" \")).toList.groupBy(x=&gt;x).mapValues(x=&gt;x.length)\r\n<\/pre>\n<p>Oops \u2014 that worked, but we once again brought the whole file into memory because the List that was created from <strong>toList<\/strong> has all lines for the file. We\u2019ll see next how to use a <em>mutable<\/em> <strong>Map<\/strong> to get around this.<\/p>\n<h2>     Word counting by streaming with an Iterator and using mutable Maps<\/h2>\n<p>In all of the tutorials so far, I\u2019ve pretty much stuck to immutable data structures except when mutable ones show up due to context (like Arrays coming out of the <strong>toString<\/strong> method). It\u2019s good to try to make use of immutable data structures where possible, but there are times when mutable ones are more convenient and perhaps more appropriate.<\/p>\n<p>With the immutable Maps we saw in the previous tutorial, you could not change the assignment to a key, nor could you add a new key.<\/p>\n<pre class=\"brush: scala;\">lettersToNumbers: scala.collection.immutable.Map[java.lang.String,Int] = Map(A -&gt; 1, B -&gt; 2, C -&gt; 3)\r\n\r\n1\r\nscala&gt; lettersToNumbers(\"A\") = 4\r\n&lt;console&gt;:9: error: value update is not a member of scala.collection.immutable.Map[java.lang.String,Int]\r\nlettersToNumbers(\"A\") = 4\r\n\r\nscala&gt; lettersToNumbers(\"D\") = 5\r\n&lt;console&gt;:9: error: value update is not a member of scala.collection.immutable.Map[java.lang.String,Int]\r\nlettersToNumbers(\"D\") = 5\r\n<\/pre>\n<p>There is another kind of Map, <strong>scala.collection.mutable.Map<\/strong>, that does allow this sort of behavior.<\/p>\n<pre class=\"brush: scala;\">scala&gt; import scala.collection.mutable\r\nimport scala.collection.mutable\r\n\r\nscala&gt; val mutableLettersToNumbers = mutable.Map(\"A\"-&gt;1, \"B\"-&gt;2, \"C\"-&gt;3)\r\nmutableLettersToNumbers: scala.collection.mutable.Map[java.lang.String,Int] = Map(C -&gt; 3, B -&gt; 2, A -&gt; 1)\r\n\r\nscala&gt; mutableLettersToNumbers(\"A\") = 4\r\n\r\nscala&gt; mutableLettersToNumbers(\"D\") = 5\r\n\r\nscala&gt; mutableLettersToNumbers\r\nres4: scala.collection.mutable.Map[java.lang.String,Int] = Map(C -&gt; 3, D -&gt; 5, B -&gt; 2, A -&gt; 4)\r\n<\/pre>\n<p>It also has a handy way to increase the count associated with a key, using the <strong>+=<\/strong> method.<\/p>\n<pre class=\"brush: scala;\">scala&gt; mutableLettersToNumbers(\"D\") += 5\r\n\r\nscala&gt; mutableLettersToNumbers\r\nres6: scala.collection.mutable.Map[java.lang.String,Int] = Map(C -&gt; 3, D -&gt; 10, B -&gt; 2, A -&gt; 4)\r\n<\/pre>\n<p>However, we can\u2019t use that method with a key that doesn\u2019t exist.<\/p>\n<pre class=\"brush: scala;\">scala&gt; mutableLettersToNumbers(\"E\") += 1\r\njava.util.NoSuchElementException: key not found: E\r\n&lt;...stacktrace...&gt;\r\n<\/pre>\n<p>Fortunately, we can provide a default. Here\u2019s an example of starting a new Map with a default of 0.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val counts = mutable.Map[String,Int]().withDefault(x=&gt;0)\r\ncounts: scala.collection.mutable.Map[String,Int] = Map()\r\n\r\nscala&gt; counts(\"Z\") += 1\r\n\r\nscala&gt; counts(\"Y\") += 1\r\n\r\nscala&gt; counts(\"Z\") += 1\r\n\r\nscala&gt; counts\r\nres11: scala.collection.mutable.Map[String,Int] = Map(Z -&gt; 2, Y -&gt; 1)\r\n<\/pre>\n<p><em>Note<\/em>: when you start with some values already in a Map, Scala can infer the types of the keys and the values, but when initializing an empty Map, it is necessary to explicitly declare the key and value types.<\/p>\n<p>With this in hand, here is how we can use <strong>flatMap<\/strong> plus a mutable Map to count words in a text without reading the entire text into memory.<\/p>\n<pre class=\"brush: scala;\">import scala.collection.mutable\r\nval counts = mutable.Map[String, Int]().withDefault(x=&gt;0)\r\nfor (token &lt;- scala.io.Source.fromFile(\"pg1661.txt\").getLines.flatMap(x =&gt;x.split(\"\\\\s+\")))\r\ncounts(token) += 1\r\n<\/pre>\n<p>Having created the counts Map in this way, we can convert it to an immutable Map with the <strong>toMap<\/strong> method once we are done adding elements.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val fixedCounts = counts.toMap\r\nfixedCounts: scala.collection.immutable.Map[String,Int] = Map(wood-work, -&gt; 1,\r\n&lt;...output truncated...&gt;\r\n<\/pre>\n<p>Now we can\u2019t modify the values on <em>fixedCounts<\/em>, which has advantages in many contexts, e.g. we can\u2019t accidentally destroy values or add unwanted keys, and there are (positive) implications for parallel processing.<\/p>\n<pre class=\"brush: scala;\">scala&gt; fixedCounts(\"Holmes\") = 0\r\n&lt;console&gt;:13: error: value update is not a member of scala.collection.immutable.Map[String,Int]\r\nfixedCounts(\"Holmes\") = 0\r\n^\r\n<\/pre>\n<h2>     Reading a file from a URL<\/h2>\n<p>As it turns out <strong>scala.io.Source<\/strong> can do a lot more than read from a file. Another example is to read from a URL to access a file on the internet, using the <strong>fromURL<\/strong> method.<\/p>\n<pre class=\"brush: scala;\">val holmesUrl = \"\"\"http:\/\/www.gutenberg.org\/cache\/epub\/1661\/pg1661.txt\"\"\"\r\nfor (line &lt;- Source.fromURL(holmesUrl).getLines)\r\nprintln(line)\r\n<\/pre>\n<p>If you are just going to analyze the same file again and again, this is probably not what you need \u2014 just download the file and use it locally. However, it can be quite useful in contexts where you are exploring links within pages (e.g. while processing Wikipedia or Twitter data) and need to read in content from URLs on the fly.<\/p>\n<h2>     Use (up) the Source<\/h2>\n<p>A final note on the Iterators you get with Source.fromFile and Source.fromURL: you can only iterate through them once! This is part of what makes them more efficient \u2014 they aren\u2019t holding all thattext in memory. So, don\u2019t be surprised if you get the following behavior.<\/p>\n<pre class=\"brush: scala;\">scala&gt; val holmesIterator = Source.fromFile(\"pg1661.txt\").getLines\r\n holmesIterator: Iterator[String] = non-empty iterator\r\n\r\nscala&gt; holmesIterator.foreach(println)\r\n\r\nProject Gutenberg's The Adventures of Sherlock Holmes, by Arthur Conan Doyle\r\n\r\nThis eBook is for the use of anyone anywhere at no cost and with\r\n almost no restrictions whatsoever.  You may copy it, give it away or\r\n re-use it under the terms of the Project Gutenberg License included\r\n with this eBook or online at www.gutenberg.net\r\n\r\n&lt;...many lines of output...&gt;\r\n\r\nThis Web site includes information about Project Gutenberg-tm,\r\n including how to make donations to the Project Gutenberg Literary\r\n Archive Foundation, how to help produce our new eBooks, and how to\r\n subscribe to our email newsletter to hear about new eBooks.\r\n\r\nscala&gt; holmesIterator.foreach(println)\r\n\r\n&lt;...nothing output!...&gt;\r\n<\/pre>\n<p>So, the Iterator is used up! If you want to go through the file again, you\u2019ll need to spin up a new Iterator just like you did the first time around. The neat thing about staying with the Iterators and not converting to Lists (and thus bringing everything into memory) is that each mapping operation we do on the Iterator applies only for the current item we are looking at, so we never need to read the whole file into memory.<\/p>\n<p>Of course, if you have a reasonably small file to work with, you should feel absolutely free to <strong>toList<\/strong> it and work with it that way if you prefer \u2014 it will often be more convenient since you can do the <strong>groupBy<\/strong> and <strong>mapValue<\/strong> pattern.<\/p>\n<p><strong><i>Reference: <\/i><\/strong><a href=\"http:\/\/bcomposes.wordpress.com\/2011\/09\/19\/first-steps-in-scala-for-beginning-programmers-part-8\/\">First steps in Scala for beginning programmers, Part 8<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Jason Baldridge at the <a href=\"http:\/\/bcomposes.wordpress.com\/\">Bcomposes<\/a> blog.<\/p>\n<p><strong><i>Related Articles :<\/i><\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/scala-tutorial-scala-repl-expressions.html\">Scala Tutorial &#8211; Scala REPL, expressions, variables, basic types, simple functions, saving and running programs, comments<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/scala-tutorial-tuples-lists-methods-on.html\">Scala Tutorial &#8211; Tuples, Lists, methods on Lists and Strings<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/scala-tutorial-conditional-execution.html\">Scala Tutorial &#8211; conditional execution with if-else blocks and matching<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-iteration-for.html\">Scala Tutorial &#8211; iteration, for expressions, yield, map, filter, count<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions.html\">Scala Tutorial &#8211; regular expressions, matching<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html\">Scala Tutorial &#8211; regular expressions, matching and substitutions with the scala.util.matching API<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-maps-sets-groupby.html\">Scala Tutorial &#8211; Maps, Sets, groupBy, Options, flatten, flatMap<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-objects-classes.html\">Scala Tutorial &#8211; objects, classes, inheritance, traits, Lists with multiple related types, apply<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scripting-compiling-main.html\">Scala Tutorial &#8211; scripting, compiling, main methods, return values of functions<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html\">Scala Tutorial &#8211; SBT, scalabha, packages, build systems<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-code-blocks-coding-style.html\">Scala Tutorial &#8211; code blocks, coding style, closures, scala documentation project<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/fun-with-function-composition-in-scala.html\">Fun with function composition in Scala<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/08\/how-scala-changed-way-i-think-about-my.html\">How Scala changed the way I think about my Java Code<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/testing-with-scala.html\">Testing with Scala<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/12\/things-every-programmer-should-know.html\">Things Every Programmer Should Know<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Preface This is part 8 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other resources on the links page of the Computational Linguistics course I\u2019m creating these for. Additionally you can find this and other tutorial series on the JCG Java &hellip;<\/p>\n","protected":false},"author":67,"featured_media":227,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[235],"class_list":["post-641","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scala","tag-scala-tutorial"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Scala Tutorial - scala.io.Source, accessing files, flatMap, mutable Maps - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"PrefaceThis is part 8 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Scala Tutorial - scala.io.Source, accessing files, flatMap, mutable Maps - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"PrefaceThis is part 8 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2011-10-07T16:35:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T20:31:12+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jason Baldridge\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/jasonbaldridge\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jason Baldridge\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"17 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html\"},\"author\":{\"name\":\"Jason Baldridge\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/95ef2670a4040b0f7101c48dba2795c0\"},\"headline\":\"Scala Tutorial &#8211; scala.io.Source, accessing files, flatMap, mutable Maps\",\"datePublished\":\"2011-10-07T16:35:00+00:00\",\"dateModified\":\"2012-10-21T20:31:12+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html\"},\"wordCount\":1857,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"keywords\":[\"Scala Tutorial\"],\"articleSection\":[\"Scala\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html\",\"name\":\"Scala Tutorial - scala.io.Source, accessing files, flatMap, mutable Maps - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"datePublished\":\"2011-10-07T16:35:00+00:00\",\"dateModified\":\"2012-10-21T20:31:12+00:00\",\"description\":\"PrefaceThis is part 8 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/10\\\/scala-tutorial-scalaiosource-accessing.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JVM Languages\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/jvm-languages\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Scala\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/jvm-languages\\\/scala\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Scala Tutorial &#8211; scala.io.Source, accessing files, flatMap, mutable Maps\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/95ef2670a4040b0f7101c48dba2795c0\",\"name\":\"Jason Baldridge\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g\",\"caption\":\"Jason Baldridge\"},\"sameAs\":[\"http:\\\/\\\/bcomposes.wordpress.com\\\/\",\"http:\\\/\\\/www.linkedin.com\\\/pub\\\/jason-baldridge\\\/5\\\/629\\\/9b2\",\"https:\\\/\\\/x.com\\\/http:\\\/\\\/twitter.com\\\/jasonbaldridge\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/jason-baldridge\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Scala Tutorial - scala.io.Source, accessing files, flatMap, mutable Maps - Java Code Geeks","description":"PrefaceThis is part 8 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html","og_locale":"en_US","og_type":"article","og_title":"Scala Tutorial - scala.io.Source, accessing files, flatMap, mutable Maps - Java Code Geeks","og_description":"PrefaceThis is part 8 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other","og_url":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2011-10-07T16:35:00+00:00","article_modified_time":"2012-10-21T20:31:12+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","type":"image\/jpeg"}],"author":"Jason Baldridge","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/jasonbaldridge","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Jason Baldridge","Est. reading time":"17 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html"},"author":{"name":"Jason Baldridge","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/95ef2670a4040b0f7101c48dba2795c0"},"headline":"Scala Tutorial &#8211; scala.io.Source, accessing files, flatMap, mutable Maps","datePublished":"2011-10-07T16:35:00+00:00","dateModified":"2012-10-21T20:31:12+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html"},"wordCount":1857,"commentCount":1,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","keywords":["Scala Tutorial"],"articleSection":["Scala"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html","url":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html","name":"Scala Tutorial - scala.io.Source, accessing files, flatMap, mutable Maps - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","datePublished":"2011-10-07T16:35:00+00:00","dateModified":"2012-10-21T20:31:12+00:00","description":"PrefaceThis is part 8 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"JVM Languages","item":"https:\/\/www.javacodegeeks.com\/category\/jvm-languages"},{"@type":"ListItem","position":3,"name":"Scala","item":"https:\/\/www.javacodegeeks.com\/category\/jvm-languages\/scala"},{"@type":"ListItem","position":4,"name":"Scala Tutorial &#8211; scala.io.Source, accessing files, flatMap, mutable Maps"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/95ef2670a4040b0f7101c48dba2795c0","name":"Jason Baldridge","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g","caption":"Jason Baldridge"},"sameAs":["http:\/\/bcomposes.wordpress.com\/","http:\/\/www.linkedin.com\/pub\/jason-baldridge\/5\/629\/9b2","https:\/\/x.com\/http:\/\/twitter.com\/jasonbaldridge"],"url":"https:\/\/www.javacodegeeks.com\/author\/jason-baldridge"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/641","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/67"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=641"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/641\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/227"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=641"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=641"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}