Are we on hi hello everyone you're here to hear about guava if you're not here to hear about guava please stay anyway and listen to us talk about guava uh my name is Kevin Buran and I'm Kirk L and uh looks like we can get started uh what is guava uh guava is a suite of the common utility libraries that we have found the most useful at Google across all of our thousands of java projects that we have at Google so we talking about collections concurrency utilities for working with Primitives reflection etc etc uh we
have found that no matter what kind of application we're building whether it's server side whether it's in the browser using git or on a phone uh these kinds of things tend to be needed again and again and so uh the way we think about it is the Things that you might have expected to find in the jdk but one more level above that the jdk plus plus plus however many pluses you want to give it and it's released to you under Apache 2.0 license why do we do this uh guava's goal is pretty clear we
want you to write less code we want you to accomplish the same things and have less code to write to do it but also we want to make sure that the code that you do write is as Simple and Clean and Readable as it can be so if your utility libraries that you're using don't have the exact right behavior and you have to work around them it makes your code harder to understand if your utility libraries have uh not very well- named classes and methods then when you read your code you're going to be calling
not very well- named classes of methods it makes your code harder to understand so our goal here is really not about our code it's about what can we do for your Code to make your code the best it can be um we are on release 12.0 right now in fact we just put out a release candidate for that this week and we hope to go final with it very soon um we release every 3 months pretty much like clockwork more or less it's a train leaves the station kind of a situation uh but we try
to make sure there is significant new functionality in each release and anywhere from 30 to 40 to 50 issues Fixed kind of um what is a little bit different about guava from most libraries is that we have a mixture of apis that are marked as being API Frozen and those that are not API Frozen We Mark the non-frozen apis with an annotation called at beta all that means is that it's still subject to change but because of this it means that in every release that we make every 3 months we always have to keep bumping
the major version Number that's why we're already at 12.0 even though we've only been doing this for about 3 years uh because any of those beta apis might have changed incompatibly so it constitutes a new major version and occasionally we also need patch releases so you our last version was 11.0.2 uh what we're here to do today is give you just a very incomplete overview of some of our favorite libraries in guava um there will be some Rhyme or Reason to the choices but it'll be somewhat random as well and we would love to get
as many of your questions as we can get in as well um if you have a question that really relates to the slide we're on if there's a question that would help you understand the slide we're on better that means that your question would also help half of the people in the room understand that slide better as well so please raise your hands as conspicuously as you Can whoever is not talking at the time will be trying to watch for that we can answer that right away if your question just seems related to the slide
probably better asked at the end um and also if you're more comfortable asking your question in French we will bring our teammate Charles to the stage and he will field the French language questions that would be fine and with that okay uh so that was a a brief overview of the project uh now We're actually going to delve into some of the specific uh apis that we provide in the library uh we'll start off with the stuff that's in common base which is very uh very lowlevel stuff and we'll build up from there uh the
first uh API we present is preconditions um these are used for validating assumptions that you have right when you enter uh a code block so whether it's right in a Constructor or it's right in a at the top of a method these are assumptions That you make uh about the either the parameters you're getting uh or the state of your class and you need to assert these uh and you want to throw an unchecked uh exception if they do not hold so in this instance uh we're going to demonstrate three three different API or three
different uh methods on the preconditions class um these are I've statically imported these here um since you we tend to use these very very frequently and in almost all classes uh We recommend that people statically import them so the check not null is actually preconditions do check. n so it's a static method on preconditions uh similarly with check argument and check state so check not null uh you pass it a reference to an object if it's null it simply throws a null pointer exception um this is really useful in Constructors uh because typically if you
if you didn't check not know the the incoming argu uh parameters in your Constructor Later on you might try to use you know call a method on the engine and you'll blow up then so it's it's really better to fail fast in this in this situation so here we check not null the engine to make sure that the car does indeed have an engine and not a null reference uh later on we have a method called Drive uh we want to assert a few things before we actually try to drive the car the first thing
we need we want to assert is that the speed is actually a Positive speed um because it doesn't make sense to to have a negative speed so here we actually are using um there's a a string substitution that you can use so you can actually in your debugging output uh in the illegal argument exception we'll get the contents of this string so we'll actually substitute this the uh speed in if this check if this precondition doesn't hold uh second we check that the engine is actually running because you can't drive A car unless the engine
is running so we also use this check State um the check state will throw an illegal State exception uh if the engine dot is running returns false uh moving on this is a completely separate API but uh this is something that makes implementing uh object. two string a lot easier so instead of you know using a bunch of string concatenations or a string Builder to build up your your two string uh return Value this objects. two string helper makes it a lot easier so basically invoke it like this you keep adding on all the different
primitive types uh or other objects that you have in uh as a field in your class and then you just call two string on it um in this instance uh the pet name string uh field in this class is actually nullable so if you use the omit null values option on the two string helper then it will actually it Won't print that field in output if you don't have that uh option on then it will actually just print pet equals null um it depends on how you want to format the output for your two string
uh stopwatch this is preferable to use over system. nanotime or system. current milliseconds instead of having to do the subtraction yourself and keep uh state in a local you know long variable um what you can do is you create a Stopwatch instance and then you can start the stopwatch and start the stopwatch and later stop the stopwatch when you're done with whatever operation you're trying to time so in this instance um we are doing some some other operations this this could be some long operation that you want to time and maybe you know watch the
ver watch what how long this uh operation usually takes um when you're done you can just call stopwatch do Elaps milles the stopwatch will will continue to run at that point um but if you'd like to explicitly stop it you can also call a stopwatch that stop if you want to get it in some other format like uh NS or minutes or you know whatever time unit you want you can also get that from this API as well um it's also important to note this that this meas measures uh relative timing so it's not absolute
timings like system. current uh time alies or system. Nano Time so this is just a lapse time from when you started the stopwatch till when you stop the stopwatch okay uh string splitting quiz can anyone tell me what the uh that split statement at the top will do who thinks it's a a few B nfu c d okay so majority said D it's actually A um the semantics of uh string. split are pretty IL defined and it's it's obviously complicated uh to know without testing so but what we probably want is actually B Because assume
this input comes from some user who's typing in a field and you asked him for comma you know separated list of uh of inputs so probably what we want is we want to only get the the different uh inputs there with the delos stripped out so to do this with string. split as as we saw It's not easy so we have this class called a splitter uh the splitter you define what your delimiter is in this case we're using a comma and then there's other options you can add to this uh splitter class the splitter
instance to split as you desire um so like I said it's a basically a more intuitive string. spit uh it doesn't silent silently discard the trailing separators as string. split did um and IT hand handles empty pieces Predictably meaning that it it it gives you options to either um omit them or trim the uh the individual pieces so in the previous slide here we're going to trim the results so that's going to trim off any white space from each piece that we've done uh and we're also going to emit empty strings so we don't want
an empty string in the the results so this class gives you a lot of configurability for splitting uh strings which is useful for user Input uh so similarly to string splitting we also have string joining uh Joiner is basically does the opposite it concatenates a bunch of different strings using a delimiter uh if any of the strings that you're passing in happen to be null we'll throw a null poin or exception um unless you specify one of these two options either skip nulls which does exactly what it says it'll just skip right past the null
inputs or you can use use for null and That you can substitute in another string literal like you could substitute in the string unknown so in this case we're going to join on a comma space and we're going to skip any nulls and then when we call joiner. jooin we pass a several different uh string inputs and will actually yield pretty much exactly what we want for our output um this really helps if you're ever joining strings in a you know for user visible uh output so you don't have to have you Know is a
Boolean is this the first piece in the to join uh charm matcher this is basically breaks down into two steps the first step is you have to Define what is a matching character so we've defined a bunch of uh predefined ones like Whit space asy any which matches any character Etc digit uh and these are static constants on the charm matri class uh or if you want you can Define your own so if you want to say is this The X character or is this not the X character um or you can say is this
one of you know any of these characters in this string or you can use ranges as well uh or if you like you can also subass charm matcher and Implement matches directly so once you define what characters this uh charm matcher will match you have to say what to do with these uh what to do with the charm Metra then so there's a whole list of uh different options here I'm not going to Go through them all but uh you can basically either um ask booing queries like does it match anything or you can get
uh a numeric answer back for the index you can also remove trim and collapse uh from these these charm mattres from your inputs so for example to scrub a user ID let's say the user ID is only uh digits and dashes we can use charm meter that digit so that's that will match all digits you can actually join these charm mates together using or So we say it's a digit or it's a dash and then we retain that from the user input so if the user typed in other characters the result will actually only be
digits or dashes okay optional this is an immutable wrapper that either is in two states it's either present which means it contains a n nonn null reference or it's absent and it never contains null so an absent optional contains nothing it doesn't Contain a null reference uh possible uses for the optional class as a return type so instead of returning null or a nullable foo you can return an optional Foo then uh people won't if they try to D reference whatever they uh get back from the method they won't no pointer out right away they'll
have the option of seeing if that optional is present or not um you can also use it for other things like if you'd like to uh store um Instances in a collection that doesn't support null values like any of our meable collections they don't support null values so you could wrap them in an optional so um yeah let's see there's a few different ways to create an optional um you can either do optional. of that requires that your reference that you're passing it is non-null you can also do optional. absent that explicitly says this is
an absent optional there's uh and then Optional. from nullable from nullable actually will take a nullable reference if you pass the nullable reference it'll return you optional. absent if you pass it a non-n reference it'll return you optional. of uh so once you have this optional of T to unwrap it you have a few different options as well if you call get on it it'll return you the contained uh instance if it if that optional was actually optional. absent it will throw an illegal state state Exception you can also use this to do uh easy
defaults so if you have an optional you can say optional. or a default value this is useful so if the optional isn't present if it's an absent optional you can just pass an or which is a default value in this case we're using uh we're defaulting to utf8 um or if you the default value that you want to return from that is expensive to compute or to load or whatever you can pass it A supplier Directly so you can say your optional. or and then give it a supplier that will lazily load the uh the
default value or if you just want to get null back from this if the uh value isn't present then you can use or null uh a few other useful methods on optional itself as set this is basically a shortcut to turn your optional into an iterable it it actually returns a set but it's sometimes useful to have an optional that's an iterable the iterable Will either have zero or one elements in it uh either if it's absent it will have zero if it's present it will have one and finally optional. transform transform takes a function
which we'll get into right after this and basically function just uh trans forms one typee into another so a function function is from F to T this is a one-way transformation it takes type f and transforms it into type t uh and all you do is override one Method this apply method um the most common use for this is transforming collections into a view of that other collection um this this kind of goes into a little bit of functional programming with Java which is currently kind of messy but it can does have it uh the
right you know when used rightly it can make your code cleaner um a predicate is similar to a function in in that it's still functional programming is is uh but this only Determines true or false for a given input so here you override the apply method and you basically tell whether or not the uh reference that you pass to it is uh applies or not and the most common use for this is for filtering collections if you want to say you know give me all the um items in this collection that are you know men
or something like that so now we're going to jump up one level into common collect this is Basically all the collection related stuff that we have in guava um this is just a brief overview of of what's in there okay so this is our functional Pro programming example um here we're defining a predicate and this predicate is going to be on clients and again we're overriding the apply method uh and here we're going to determine this predicate is going to match um clients that have been active in the past month uh and we're also introducing
here Itable which is new in our guava 12 release um this lets you do basically chaining of all these different uh options here on on an iterable and it makes it very clean to read so here we're going to do fluent iterable from we're going to grab the entire Client List from the database we're going to filter out all the active we're going well filter out all the inactive clients so we're left with just active clients then we're going to transform this Collection uh or this itable rather using the two string function so we're going
to take all those client objects and call two string on them and then we're going to limit it to 10 and then bring this into a meable list so in this nice little five lines we've got here we've quered the database uh filtered out inactive clients transformed them so we're just getting the name of the client pulled out the top 10 and gotten into an immutable list uh I'll go into The this is pretty much most of the flu inable API here so there's a few different ways you can use flu nerable uh you can
either use it for chaining which uh there's a few methods you can use for chaining them these will return another instance of a fluent interval uh that you can keep working with so skip you can tell it to skip over the first 10 elements or the first n elements of your interal this will again return a fluent interval with those first Elements skipped limit you can say only give me the first five elements in this interval or 10 or whatever you have cycle will basically keep cycling the iterable indefinitely so this you can use this
however you want and then filter insurance form which we saw before these will take uh a predicate and a uh function for querying the fluent interal these return booleans uh all match or any match these will take predicates and Say do all the elements in this fluent interval match this predicate or do any of the fluent or any of the uh elements in this interval match the predicate contains is we'll take an e and that's very simple does it does this itable or not contain this element or not whether or not the flu Nal is
empty converting as we saw in the last slide you can also convert these once you have a flu interal you can convert it to a immutable list immutable set or A immutable sorted set um or you can just dump it out to an array if you'd like and then for extracting from the fluent interval you can also say give me the first element in the fluent interval the last element in the fluent interval or the first matching element in the fluent interval with a predicate um these three methods will actually return an optional so you
know if your fluent interal is empty and you call first you'll get an optional absent an absent Optional um similarly with last and first match and get just Returns the whatever element uh given an index okay so we just saw some some ways that functional programming is actually useful but you do have to be careful with it um here we've used um both a function and a predicate to uh to use this example and then we'll actually show what it would look like if you didn't use um functional programming so all of this if you
do it just the Normal way actually is much shorter so you have to use functional programming with care um don't we've seen a lot of people do this at Google unfortunately and if you use functional programming for everything it actually turns into quite a mess so just use it you know sparingly all right so also in common collect we've got a few other uh interesting uh uh data structures that are not in the jdk um a multi set which is often called a bag allows you to add Multiple instances of a given element and then
it basically counts how many instances of that element exist so it's kind of similar to a map from E to an INT but it's slightly different there's only ever positive count so there's never you know you can't have a negative count which makes sense um when you call size on the multi set it returns a total number of items not the number of keys which is if you were to use a map from EA and you would get the number of keys Uh and the iterator will actually go over each element in the multi set
so you know if you've got 10 of the string F in there you'll get Fu 10 times in the iterator and if you need something uh that supports more than just integer. max value for your accounts we have Atomic long map this is very similar but it uh uses Atomic Longs instead of ins uh multimap this is sort of similar to a map uh in that it keeps key value Pairs but these key value pairs there might be duplicates so the values can um that relate the map to a single the map to a single
key can be either viewed as a set or a list um and again this is sort of similar to a map from K to a collection of V but get never returns null so if you call get on this this U multi map you'll never get null you'll only get the uh empty collection back um contain key is true if there's one or more values uh and Again size will return similar to the multi set the total number of entries not the number of keys and if you want to just view this multimap as a
map from K to collection V you can do that as well with the asmap view um bu map this is basically a b directional map um this make sure that both your keys and your values are unique so if you it's an invertible map as well so if youd like to invert the map there's an inverse method that will Give you basically the same exact you know just the inverse of the map that you have um you can mimic this by you know having two separate Maps but maintaining those is is a pain so if
you if your values are also unique then you can use a buy map which Maps unique keys to Unique values and finally table this is basically a two tiered map um or you can think of it a map with two keys um so space you can think of it very similar To a table where you have a row and a column um and these tables can either be sparse or dense so hash Bas table is going to be backed by two hash Maps which will be a sparse table and a tree base table will be
backed with two tree Maps which will be also sparse however if your data is is densely packed like let's say you're using you know ins and you have ins and ins for your two keys you can use an array table this is backed by an actual array of whatever uh Object type you have so this will be much more densely packed um but if you have a you know non- dense uh data then this this will use a lot of memory Additionally you can get many views from this underlying data um you can view them
as column Maps row Maps uh column sets uh row sets or if you want you can just view all of the entries as a set so you can get we we've defined a new entry class that takes uh that's a three elements the row the column and The value you you can get a set of all those back and you would typically use this where instead of in your code you might see a map from R to a map from C to V you can use this instead basically when you have two um two keys
that you want to look up a single value with and immutable collections I touched on these briefly before but we offer an immutable flavor of every Java collection in the jdk as well as the ones that we just saw that we've added In guava um the benefit of me collections is that they're inherently thread safe so if you know uh if they're immutable then you don't have to worry about thread safety at all um they've also have reduced memory footprint um and slightly increased performance uh we've worked hard to make sure that these uh the
estate performance um and you would say why would we provide these if collections. unmodifiable also is already exists in the jdk the collection Of that unmodifiable actually is just a view of the underlying data so if anyone maintains a reference to that uh data structure that you've passed into that they can change what's inside of your unmodify unmodifiable uh collection so immutable or immutable collections actually perform a copy uh and they copy all the data into their uh data structure uh they're also more efficient typically than the uh the unmodifiable collections and finally the types
convey Mutability so instead of storing these as a a list of Fu uh we actually use mutable list as the type um so even though it's not an interace think of it as a as an interface that is you know immutability is is right there in the interface name I'm going to pass this off to Kevin now oh yeah uh question in the front um so as you maintain a reference it's a Shallow copy yeah so your elements don't have to be clonable or anything like that okay uh yeah the question is whether doing a
copy of an immutable collection is deep or shallow the answer is it's shallow so I don't know about you but my favorite thing in Java is implementing comparators and I if I could write my project by just chaining together the right 340 comparators that would be awesome I mean how many of you just love Writing code like this I hear some the microphone system loves it uh so this is fairly tedious and as we'll see it's actually fairly bug prone um we offer a couple of libraries to help you rewrite this one of them is
called comparison chain so you're still going to implement comparator or comparable but you have a very easy way to provide your comparison logic in a single statement you simply say you know the first thing I want to Do is get the offset for each of them and compare them and notice here let me go back to the previous slide right here who can tell whether this is doing a normal comparison or a reverse comparison when I say int result equals offset 2 minus offset one who looks at that and immediately thinks that's a reverse comparison
I know when I look at it I stop and I think if this one's one and it takes me a minute here using Comparison chain you can simply see that I've passed in TZ id2 first and TZ id1 second so I'm doing a reverse comparison which is good because the variable is named by reverse offset then name uh In the comparison chain as soon as it gets a value that is a positive or negative result meaning it can decide which one is greater or lesser it actually short circuits the rest of the computation this this
comparison of the time zone IDs won't actually happen due To some magic in the implementation um so if the time zone IDs are tied though then it continues on to compare by the time zone IDs we keep getting a lot of feedback on this mic I don't know if there's anything we can do about that um so the comparison chain also you know it has overloads to compare all the Primitive types like ins and Longs and doubles and it also has methods for comparing Booleans so you can call compare false first or compare true first
and Al if you want to compare objects with a specific comparator you can pass that in as well so uh you know it's short circuiting it never actually has to allocate any instances and uh it turns out to be pretty fast for those reasons uh yeah question the question is whether it uses a thread local doesn't do anything like That I even described it as magic but it's not actually even magic when you look at the code it's it turns out to be very simple uh so I'll just let people go and look up that
code online if they if they want to see how it really works uh here's another way that you can do it and you know which way is better depends on the situation you can also construct your comparator without actually having to implement comparator At all do it sort of declaratively uh using the ordering class so what we're going to do is we're going to start off with a natural ordering then we're going to reverse it then we're going to say apply that reverse natural ordering to the result of this function and then if that ties
we will continue on with the compound method to then use natural ordering and I I didn't actually run the unit tests on this Slide so I might have actually messed that up a little bit but imagine that it does the exact same thing as this because it should um what you see here is uh you know this is no shorter than the other slide was because we have to write out this entire function but hopefully when we get our Lambda expressions in jdk8 this will become actually quite Pleasant um again you know in this example
I would probably go with the Comparison chain instead of the ordering but you're going to find cases where one is more useful than the other I think this slide is still probably not completely self-explanatory so I'm going to go into a little bit more depth about what ordering really is so an ordering is a class that implements comparator so once you have an ordering you can use it anywhere that you would use a comparator and it's very similar to that fluent iterable that we showed you earlier uh We we you could think of this as
being fluent comparator uh hold on all right common ways to get one of these orderings to start with you can just start with the natural ordering or you could implement it yourself just like we Implement um comparator just simply Implement ordering instead if you happen to already have a comparator instance sitting around then you can use ordering. from to turn that into an Ordering uh you don't really ever need to say ordering. from new comparator and then implement the comparator there's no reason to do that because you can simply extend ordering in the first place
and there are a few other ways to create an ordering this is an explicit ordering it says look I'm going to tell you exactly what order these strings should appear in and then you name the exact set of strings that you're going to be able to sort in what order they appear in this Actually comes in useful sometimes uh once you have an ordering then you can use the chaining methods to chain it into an altered version of that ordering so if you call reverse on the ordering now you've magically got a comparator that compares
things in the opposite order uh you could compound it with another comparator again that means use the first comparator as long as it tells you which one is lesser or greater but if they turn out to be tied that neither One is lesser and neither one's greater then go on to try the next comparator uh we already saw the on result of function you can also say nulls first that means you write a comparator that doesn't know how to deal with null then you call nulls first on it now you've magically got a comparator that's
going to sort all null elements to the beginning of a collection and all the non-null ones as usual after that and uh I won't go into lexicographical It's kind of complic complex compared to the others and so now that you've created an ordering and you've called these chaining methods you can use that wherever you need to compare or you could use any of these really handy operations that we put right there on ordering for you so for example you could take a copy a sorted copy of an iterable you could ask whether an iterable is
already sorted you could find the Min or the max or you could Even say I want to know not just the one least element but the 10 least elements in this entire iterable with least of and greatest of okay um again ordering is better sometimes comparison chain is better sometimes but we strongly feel that either one of them beats implementing the comparator by yourself uh who in the room believes that they can uh name the three mathematical properties that every comparator implementation must have show Of hand all right sir can you shout him out reflexive
transitive and symmetric so close that is the requirements for the equals method comparator has to be reflexive transitive and anti-symmetric and I forgot what anti symmetric means and I was a math major I had to go back and look it up in my old math textbooks so it's actually when you implement these comparators by hand it is surprisingly easy to make very subtle Mistakes that cause your comparator to not function correctly and the worst thing is it may function correctly for now but when you upgrade your jdk and they change the sort algorithm that might
be the thing that suddenly exposes the bug as long as you stick to comparison chain and the ordering methods you basically can't go wrong you're basically guaranteed to get a comparator that will behave correctly according to the comparator Specification it might not sort things the way you wanted them sorted because you know you might have put the methods in the wrong order or whatever but you will get a basically valid comparator the only exception to that is if you were to use uh on result of and pass it a very badly behaved function that returned
a random value on every call or something like that uh so now we're going to go into a a little bit more detail on our new Hashing API uh why would we need a new hashing API doesn't Java have object. has code that sounds like a hashing API to me I don't know about you uh what what could be wrong with that well the way to think of object. has code is it is the hash code generating method that is good enough for inmemory hashmaps that is why why it exists it exists so that you
can have your hash maps and your hash sets and if you have a a hash map where the Hash function is has a lot of collisions where it sends the uh the same keys or different keys to the same hash code and those Collide in the hashmap they have to go into the same bucket in the hashmap in general overall that's not actually too catastrophic the the code will completely continue to work correctly and the performance drawback of having those collisions is not when I measured it is not actually as great as you might worry
that it is so object Hash code needs to be just sort of good enough for that but it is completely limited to 32bits you cannot have your 64-bit and 512-bit hashing algorithms in there and there isn't even an elegant way to create a composed hash code where this hash code is based on that hash code which is based on that one and then just only limit it down to 32 bits at the end instead you have these methods inv object. has code in perhaps a big tree of objects and it's continually Limited down to 32
bits so you're losing information you're losing the uh the hashy of the hash function to some degree if you will a bigger problem to me is there's no pluggability at all there's no separation between what data am I hashing and in which order am I hashing it versus which algorithm do I wish to use to Hash this data so if you were using MD five and then you want to do something else you may have to change a Lot of code uh finally implementations of object. has code tend very strongly to have very poor bit
dispersion uh what that means is that ideally when you have a hash code consisting of one one 1 0 0 you know these 32 bits you want to be able to select out any subset of those bits and you want to have only the expected increase in collisions so if I take only the rightmost three bits of a hash code I would like 1/8 of all elements to to produce the value Zero 1/8 of them to be one 1/8 of them to be two and so forth but if you have a weak weak hash function
depending on which bits are selected you will get more collisions than you expect and that turns out to be okay for hash code for hashmap and hashmap tries to correct for this by applying a secondary hash function to all of the hash codes that you implement but uh sometimes you need to do better sometimes s you need cryptographic hashing or you want a Reliable fingerprint for a document you you have a case where okay if this fingerprint collides it's actually bad um there are other applications like cuckoo hashing and something I'm going to show you
in a minute called Bloom filters and none of these things object. has code won't work for any of these things um I think we're okay a show time uh so to address this the jdk introduced an interface actually they introduced two Interfaces because what's twice as good as one interface to do something two there's both message digest and there's Java util zip check some and these are each named not after there's no fundamental difference between these they're simply named after different use cases for why you might be using it but they fundamentally are trying to
be the same thing and the worst part is that they're not even any fund to use at all unless you happen to be hashing a raw Bite array if you actually have a bunch of Longs you're going to have to convert those all to bite arrays and concatenate them manually uh or at least pass them in one by one um we designed an API to be a little bit more friendly to use than that so here's what our API looks like first of all you get the hash function you want so in this case we're
using murmur 3 the 128-bit version you start a hasher and then you just start pushing all the data into it that you Want to hash and of course the order that push this data in matters if you change this code to Hash the data in different order you'll get a different result and we support you know all of the Primitive types and strings you can also pass a care set or a Char set to put string if you want to character en code the data while you're hashing it you don't always want to do that
I would say you usually don't need to do that um and you can even hash any object type You want if you provide a funnel which is a specification of how to slurp the dat out of that object into the hash stream and at the end you just call hash and now you have a hash code instance that you can do anything you want with you can use it as a you can return it from an API use it as a key in a map or you know you can get a long or an INT
or you can get it as a bite array Etc and it has a nice two string method that just prints it out as hex uh a hex Number because that's how we usually tend to view uh hash codes in console output um so as I mentioned we have this unified API for all hash functions and we provide implementations of the murmur 3 algorithm which is a very well liked hashing algorithm uh we are not really hashing experts ourselves but we we we have uh asked the people who are and there's a lot of respect for
murmur 3 um we have two versions of it and they are seatable so if you have a reason to need Different ones just create different ones that are seated differently and they will be completely independent hash functions we also give adapters for md5 and Shaw 512 and so forth so that if you don't want to have to write your code to the message digest API sometimes and our API sometimes you can just use our API all the time and we also have this method called good fast hash and what that means is I don't care
Which algorithm you give me I just want one that's going to be good and fast so you would not want to use this if you are going to be persisting those hash codes and reading them again at some later date because we may change good fast hash at any time that we want to and some general also utilities provided in this API uh let me just tell you about one cool application for hashing how many people in the room have uh understand What a bloom filter is and what a bloom filter does okay I had
I had not heard of these things a few years ago they are an almost magical data structure it is a probabilistic set what that means you can ask it for containment you can say does this set contain this element but what you get is a probabilistic answer the method is called might contain and a True Result means I probably have that element and a false result means I definitely don't Have that element and if you're wondering why you know you would ever want a probabilistic set sometimes you have more elements in this thing than would
ever fit in memory but the bloom filter representation in memory is very compact compared to a giant hash Set uh the most the the use case that I like to use for Bloom filters to help you understand why You' ever use one think about a spell checker if you type In a word like siy and it highlights it as being wrong that is kind of annoying because siy is a correct spelling of a correct word in the English language unless I just typed it wrong on the slide but actually I didn't because the spell checker
worked uh but if Y which is obviously not a word in any language that I'm familiar with uh if that doesn't get flagged as an invalid word that's not actually so bad because almost certainly no one's ever going to Type that so you're you're actually going to be okay with a probabilistic check for a spell checker um and the one other use which is really much more common is simply as an optimization so if you have let's say that you have a very expensive Boolean query it's going to return true or false but it's going
to take a really long time to do it or consume a lot of resources just to come up with this true or false value if you can if it's Possible for you to enumerate all the values for which that query should return true you can create a Bloom filter go through all those values for which it should return true put them all into the bloom filter serialize that thing onto dis and now when your real Production service starts up it just deserializes the bloom filter and now when you need to run this probabilistic query check
the bloom Filter first uh and it will give you this probabilistic answer if it says definitely not true you're okay in the small percentage of cases where it says well it's probably there then you fall back on the full expensive query and when you create a bloom filter you get to specify what false positive probability you're willing to accept so a common value might be 3% I'm okay if you give a false answer 3% of the time that means you've just cut all the times That you need to do this expensive query down by a
factor of 33 I think it's magical myself I love these things um we have a package of caching utilities it contains a powerful onheat cache we're not trying to compete with EH cach or mem cach or anything like that we're not trying to compete with jsr 107 but sometimes you need a cache that's just one Cut Above a map you basically just want it to be on the Heap in memory and you want it to have some features uh we actually have a ton of very useful features in here but I'm not going to talk
about them because Charles is going to talk about them in the next session after this so if you feel like this session has been just too shallow of an overview over all these different topics we can get into some real interesting detail uh with Charles after this that's in L Fitzgerald okay and all right good Timing uh so here's slide telling you how you should contact us if you start to use guava and you need to contact anyone which we hope that you will uh if you need help with anything if you have any specific
problem how many of you already are well accustomed to posting to stack overflow when you need help okay good I hope when I come back and ask that question Next Year everyone will raise their hand it is a fantastically useful site and every time That you know virtually every time that a guava user posts a question there they get an answer really quickly and a good answer and sometimes they email questions directly to me and then they have to wait three days until I get around to responding to it so stack Overflow is a great
way to get help if you really are pretty sure you've found a defect or you want to request an enhancement uh that's our URL for reporting one of those I don't actually Expect anybody to be furiously scribbling that down but you can find it pretty easily from our main project page and we also have a mailing list which is sort of the catchall you know I just want to discuss some topic that doesn't fit neatly into those categories um I want to talk for just one minute about what you should do because this will affect
everyone sooner or later you'll be using guava and you'll want to request a new feature for It and the thing that we always have to warn people about is that it's actually very hard to get new features into guava uh it is uh a very exclusive library that tries to keep itself as small and focused as it can and it is even hard for us ourselves I can't tell you how many things you know ideas I've had that I think are great and I would really love to put them in guava but I have to
convince the whole team and I have like you know nine of these things just Sitting in an ice box somewhere so it's hard for everybody um if you want to if you have such an idea we really would encourage you to file a feature request um it will it's always a good idea to search the closed ones first but if you file one that's a duplicate we're not going to yell at you it happens not a big deal um and here is the the the uh the secret magical guide to how to convince us that
your feature is a good one what we what we really need to know Is what are you trying to do what's the best way you can do it with without your feature and then what does that code look like with your feature we want to evaluate all these features again I was mentioning this at the ear at the beginning of the talk our goal is to make your code look good so if we're going to consider adding a feature we want to see what your code looks like without it and what your code looks like
with it and if that difference is really Compelling and if we can have some you know believable argument that this is not just a niche uh you know rare need but this will actually come up for many users uh across the board then that is a very compelling feature request for us so the more that you can do to illustrate that before versus after comparison the more likely we are to uh accept your feature request but it it happens that you know there are a number of features because we've been doing This for several years
when you have a feature request that's new to you the chances are relatively high that it was actually suggested once before and rejected so don't spend too much time writing a patch before you uh speak to us about it first and uh this is about how to help us if you want to help us but uh we're kind of running out of time so in the unlikely event anyone is interested in how you can help guava just ask me after Class and uh that's it it's we have seven minutes left for questions and answers I
have uh a few uh frequently asked questions that I will go into if no one raises their hand um and I did I did ask the team to come up on stage but I didn't realize we don't actually have a handheld microphone so there may not be any point in them coming up on stage unless someone can find such a thing okay first question can you tell us more about the Optional understanding in what way better check I have some IDE okay um I so one thing is that the idea that optional of te is
the new nullable te and wherever you should have used a nullable te now optional te is the way that is a religious sort of argument that some people you know try to make it's not actually an argument that we make we provide it and we say here's Some cases that we know of where it's useful but we're not trying to present it as like you know this is the way to go um I do think there are some advantages to using an optional of te instead of a nullable t because it makes the difference clear
in the code to the type system uh you cannot just accidentally forget that you have to check for null that what you have is really nullable it's all right there and you'll you know but there are many uses For it such as simply being able to distinguish between you know I have no idea what you're asking for and yes I know what you're asking for and there is no answer for example like I ask you what your middle name is and some people don't have a middle name so they you can return an object saying
I definitively know that there is no middle name which is different from returning null which just means I I just have absolutely no idea the data is just not There and as pointed out there are collections that don't support nullable uh elements that's a trend as of jdk 1.4 or so there's been a strong leaning away from allowing nullable elements in a collection and optional lets you put that token into a collection that means know definitively not present okay in the blue standing performance performance cost of optional same as any rapper class that contains An
instance it's just a class that contains an instance so my opion [Music] because you if optional were in the jdk then the jit could could treat it specially that is probably true next question or I will go to a fact uh okay first frequently Asked question lots of people the first thing They ask us is what is the difference between you and a pachy Commons I usually it really is like the first thing people want to know what are you talking about and uh so so I made a tiny URL for you tiny url.com guava
versus Apache because I don't want to I don't really like to answer this question myself why I think that you know you should look at Guava instead of that library but this answer was posted to stack Overflow and it got 70 some up Votes so I think that it is reflective of a general Community consensus about the relative value of these libraries and I think the author of that stack Overflow answers in this audience not a of our team but I see him sitting here was very well done next question in the red have you
considered about fults and flat and all that stuff and why don't we have flat map why don't We have fold and reduce and so forth all right yes I have a slide for that here it is and the frequently asked questions where are fold and reduce and so forth and the answer is that there are libraries out there that are really trying to solve functional programming for Java we're not one of those libraries we added the types that we had a need for and then we've pretty much cut it off there uh we strongly believe
that nothing is really going to make Functional programming work nicely in Java until we finally get our jdk8 and so we've sort of put put the the breaks on continuing to add more functional features that optional you have like uh it's kind ofic toat for because we have optional that makes flat map uh then you have yeah um actually I believe now that I think about it what you're calling Flat map you know we don't use the map terminology because in Java map means Java util map but now that I think about it I think
we are adding a method like you're asking for uh to fluent iterable like we call it uh transform and con did did we do that so look for guava version 13 we might have that but in general not a lot of more functional programming support next [Music] Question uh yes H did you hear that again onid Android I've got a slide for that too what about Android okay I wish I could say guava Is Awesome on Android we haven't spent a lot of time optimizing it for Android so you may encounter a performance problem if
you do we want to hear about it and we'll we'll try to help it but we hope in the future we'll we'll be able to uh you know say a lot more about having Really benchmarked this stuff aggressively on Android uh guava 12 requires jdk 1.6 and it requires if you're going to use it with Android it requires gingerbread or newer if you're on froo or earlier you will have to stick with guava 11.0.2 and I think that's the universal times out symbol so thank you very much for coming have a great rest of your
uh con