https://www.techiedelight.com/convert-string-list-characters-java/
List<Character> chars = Lists.charactersOf(string);
List<Character> chars = Chars.asList(string.toCharArray());
public static List<Character> convert(String string) {
return new AbstractList<Character>() {
@Override
public Character get(int index) {
return string.charAt(index);
}
@Override
public int size() {
return string.length();
}
};
}
System.out.println(convert(string));
.mapToObj(e -> (char)e) // Stream<Character>
.collect(Collectors.toList());
乍看
checkArgument
與 checkState
感覺會有點像,是的!如果你只使用 assert
的話,基本上都是給個判斷條件,然後在不成立時產生錯誤。使用 checkArgument
與 checkState
的差別除了一個會丟出 IllegalArgumentException
,一個是丟出 IllegalStateException
之外,最主要的是在語義差別,checkArgument
名稱表明這個方法是用於檢查引數,而 checkState
名稱表明,這個方法是用於檢查物件的狀態。CacheBuilder.build()
returns a non-loading cache. Just what you want. Just useCache<String, String> cache = CacheBuilder.newBuilder().build();
CacheLoader<String, String> loader;
loader =
new
CacheLoader<String, String>() {
@Override
public
String load(String key) {
return
key.toUpperCase();
}
};
LoadingCache<String, String> cache;
cache = CacheBuilder.newBuilder().maximumSize(
3
).build(loader);
Note: Many soft references may affect the system performance – it’s preferred to use maximumSize().
Now, let’s see how to handle cache null values. By default, Guava Cache will throw exceptions if you try to load a null value – as it doesn’t make any sense to cache a null.
But if null value means something in your code, then you can make good use of the Optional class as in the following example:
The biggest single reason that
checkNotNull
returns its argument is so it can be used in constructors, like so:public Foo(Bar bar) {
this.bar = checkNotNull(bar);
}
But the main reason that
checkArgument
doesn't do something similar is that you'd have to pass the argument separately anyway, and it just doesn't seem worth it -- especially with more complicated precondition checks, which can sometimes be more readable on their own line. Just because something can be a one-liner doesn't mean that it should be, if it doesn't increase readability.natural() | Uses the natural ordering on Comparable types. |
usingToString() | Compares objects by the lexicographical ordering of their string representations, as returned by toString() . |
But the more common way to create a custom
Ordering
is to skip the Comparator
entirely in favor of extending the Ordering
abstract class directly:Ordering<String> byLengthOrdering = new Ordering<String>() {
public int compare(String left, String right) {
return Ints.compare(left.length(), right.length());
}
};
Method | Description |
---|---|
reverse() | Returns the reverse ordering. |
nullsFirst() | Returns an Ordering that orders nulls before non-null elements, and otherwise behaves the same as the original Ordering . See also nullsLast() |
compound(Comparator) | Returns an Ordering which uses the specified Comparator to "break ties." |
lexicographical() | Returns an Ordering that orders iterables lexicographically by their elements. |
onResultOf(Function) | Returns an Ordering which orders values by applying the function to them and then comparing the results using the original Ordering . |
List<Integer> integers = Arrays.asList(3, 2, 1);
integers.sort(Ordering.natural());
Ordering<Person> ordering = Ordering
.natural()
.nullsFirst()
.onResultOf(
new
Function<Person, Comparable>() {
@Override
public
Comparable apply(Person person) {
return
person.age;
}
});
persons.sort(ordering);
https://openhome.cc/Gossip/CodeData/GuavaTutorial/Ordering.html
Collections.sort(names,
Ordering.natural().reverse().nullsFirst()
.onResultOf(new Function<String, Integer>() {
@Override
public Integer apply(String p) {
return p == null ? null : p.length();
}
})
);
Ordering
本身就是比較器,這看看它的類別定義就知道了:Collections.sort(names,
Ordering.natural().reverse().nullsFirst()
.onResultOf(p -> p == null ? null : p.length())
);
public abstract class Ordering<T> extends Object implements Comparator<T>
https://www.leveluplunch.com/java/tutorials/008-using-guava-fluent-ordering-comparator-part1/ Collections.sort(numbers, Ordering.natural().reversed());
Integer maxValue = Ordering.natural().max(numbers);
Integer minValue = Ordering.natural().min(numbers);
Comparator<String> byLength = new Comparator<String>() {
public int compare(String left, String right) {
return Integer.compare(left.length(), right.length());
}
};
Comparator<String> reversedByLength = Ordering.from(byLength).reversed();
Collections.sort(random, reversedByLength);
assertTrue(Ordering.from(reversedByLength).isOrdered(random));
Ordering by field
https://github.com/google/guava/wiki/CommonObjectUtilitiesExplained
ComparisonChain
performs a "lazy" comparison: it only performs comparisons until it finds a nonzero result, after which it ignores further input. public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(this.aString, that.aString)
.compare(this.anInt, that.anInt)
.compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
.result();
}
https://myshittycode.com/2013/12/28/java-performing-2-key-lookup-using-hashbasedtable/HashBasedTable<String, String, String> hashBasedTable = HashBasedTable.create();
hashBasedTable.put("key1", "key2", "mike");
String value = hashBasedTable.get("key1", "key2"); // "mike"
https://stackoverflow.com/questions/31422443/best-practices-for-using-multi-level-hashmap-in-java
Alternatively, one could look into a Guava
Table
, as that does the same sort of thing, with a better interface to it (something like the one I have above).
Multi-level HashMaps are not necessarily bad, it depends on your algorithm. The bad thing is that it's more difficult to manage. Consider using interfaces (something like repository) for HasMap values, this may make your design cleaner. Other option is to use composite keys in a HashMap.
Apache
2
3
4
5
6
| MultiKeyMap multiKeyMap=MultiKeyMap.decorate( new LinkedHahMap()) multiKeyMap.put( "key1" , "key2" , "key3" , "value1" ) // Last parameter is value against defined keys. multiKeyMap.put( "key11" , "key22" , "key33" , "key44" , "value11" ) multiKeyMap.put( "key111" , "key222" , "key333" , "value111" ) multiKeyMap.put( "key1111" , "key2222" , "value1111" ) |
This is how we create a map with multiple keys. Now let’s see how to fetch value out of multiKeyMap for one combination of keys.
PS :- One point to note is you have to provide combination of key in the same sequence that you provided while puting into map.
MultiKey which is again an another way to solve above use case.A MultiKey allows multiple map keys to be merged together
MultiKey multiKey=
new
MultiKey(
"key1"
,
"key2"
,
"key3"
)
MultikeyMap multiKeyMap=MultiKeyMap.decorator(
new
LinkedHashMap())
//Map map = new HashMap(); you can also use simple Map while using Multikey.
multiKeyMap.put(multiKey,
"value1"
)
//To fetch value from map using multikey, we simply do as follows :-
multiKeyMap.get(multiKey)
this.cache = CacheBuilder.newBuilder()
.maximumSize(10)
.expireAfterAccess(5, TimeUnit.SECONDS)
.build(new CacheLoader<String, Record>() {
@Override
public Record load(String key) throws Exception {
return getFromDatabase(key);
}
});
cache.get(KEY2).data
http://stackoverflow.com/questions/12721735/how-to-receive-difference-of-maps-in-java
How about google guava?:
Maps.difference(map1,map2)
http://stackoverflow.com/questions/4283351/how-to-replace-special-characters-in-a-stringString alphaOnly = input.replaceAll("[^\\p{Alpha}]+","");
String alphaAndDigits = input.replaceAll("[^\\p{Alpha}\\p{Digit}]+","");
(All of these can be significantly improved by precompiling the regex pattern and storing it in a constant)
Or, with Guava:
private static final CharMatcher ALNUM =
CharMatcher.inRange('a', 'z').or(CharMatcher.inRange('A', 'Z'))
.or(CharMatcher.inRange('0', '9')).precomputed();
// ...
String alphaAndDigits = ALNUM.retainFrom(input);
https://github.com/google/guava/wiki/GraphsExplainedGraph<Integer> graph = GraphBuilder.directed().build(); // graph is empty graph.putEdge(1, 2); // this adds 1 and 2 as nodes of this graph, and puts // an edge between them if (graph.nodes().contains(1)) { // evaluates to "true" ... }http://stackoverflow.com/questions/304268/getting-a-files-md5-checksum-in-java
Guava now provides a new, consistent hashing API that is much more user-friendly than the various hashing APIs provided in the JDK. See Hashing Explained. For a file, you can get the MD5 sum, CRC32 (with version 14.0+) or many other hashes easily:
HashCode md5 = Files.hash(file, Hashing.md5());
byte[] md5Bytes = md5.asBytes();
String md5Hex = md5.toString();
HashCode crc32 = Files.hash(file, Hashing.crc32());
int crc32Int = crc32.asInt();
// the Checksum API returns a long, but it's padded with 0s for 32-bit CRC
// this is the value you would get if using that API directly
long checksumResult = crc32.padToLong();
https://github.com/google/guava/wiki/HashingExplainedOnce a
Hasher
has been given all its input, its hash()
method can be used to retrieve a HashCode. (The behavior of hash()
is unspecified if called more than once.) HashCode
supports equality testing and such, as well as asInt()
, asLong()
, asBytes()
methods, and additionally, writeBytesTo(array, offset, maxLength)
, which writes the first maxLength
bytes of the hash into the array.Hasher hasher = hf.newHasher().putString("123", Charsets.UTF_8);
System.out.println(hasher.hash());
System.out.println(hasher.hash());
Exception in thread "main" java.lang.IllegalStateException: Cannot re-use a Hasher after calling hash() on it
at com.google.common.base.Preconditions.checkState(Preconditions.java:174)
at com.google.common.hash.MessageDigestHashFunction$MessageDigestHasher.checkNotDone(MessageDigestHashFunction.java:149)
at com.google.common.hash.MessageDigestHashFunction$MessageDigestHasher.hash(MessageDigestHashFunction.java:154)
BloomFilter<Person> friends = BloomFilter.create(personFunnel, 500, 0.01);
for(Person friend : friendsList) {
friends.put(friend);
}
// much later
if (friends.mightContain(dude)) {
// the probability that dude reached this place if he isn't a friend is 1%
// we might, for example, start asynchronously loading things for dude while we do a more expensive exact check
}
https://plus.google.com/+googleguava/posts/hfBvW6xSt8y2) If you’re hashing a String, don’t use String#getBytes. Instead, let us do the conversion to bytes for you.
Hashing.md5().hashBytes(myString.getBytes(Charsets.UTF_8)); // Don’t do this.
Hashing.md5().hashString(myString, Charsets.UTF_8); // Do this!
More importantly, never use the parameter-less version of String#getBytes because it silently uses the default Charset under the hood [2] (which is bad bad bad).
3) Instead of converting your HashCode instance to a primitive (like an int or long), instead use HashCode as a first class object! It’s simple, immutable, thread-safe, and suitable for adding to collections or exposing in APIs.
int hash = Hashing.md5().hashBytes(bytez).asInt(); // Don’t do this.
HashCode hash = Hashing.md5().hashBytes(bytez); // Do this!
In this example, we’re also losing bits of our hash code by collaring the 128-bit MD5 HashCode instance down to only 32-bits. The HashCode instance retains the full hash of the data.
https://www.baeldung.com/guava-joiner-and-splitter-tutorial
String result = Joiner.on(",").join(names);
List<String> result = Splitter.on("-").trimResults()
.splitToList(input);
String result = Joiner.on(",").useForNull("nameless").join(names);
String result = Joiner.on(" , ").withKeyValueSeparator(" = ")
.join(salary);
List<String> result = Splitter.on("-").trimResults()
.splitToList(input);
Map<String, String> result = Splitter.on(",")
.withKeyValueSeparator("=")
.split(input);
8. Split String with multiple separators
String input =
"apple.banana,,orange,,."
;
List<String> result = Splitter.onPattern(
"[.,]"
)
.omitEmptyStrings()
.splitToList(input);
List<String> result = Splitter.on(",")
.limit(4)
.splitToList(input);
http://www.diguage.com/archives/143.html
Map
相关的 Joiner
和 Splitter
第一个问题:D瓜哥需要从 URL 中获取相关请求的参数,并且将其转化成
Key-Value
形式放到 Map
对象,方便后续操作。
URL 中,参数的格式大家应该都了解:
http://www.diguage.com?userName=diguage&sex=fale
。以 ?
分割后,后面的就是参数。如果自己手动写,还有一个一个分割,实在是懒得动手了。其实 Guava中内置了非常方便的方法来解决这个问题。代码如下:int paramSeparater = url.indexOf("?"); String host = url.substring(0, paramSeparater); String params = fromUrl.substring(paramSeparater + 1); Map<String, String> paramMap = Maps.newHashMap(); Map<String, String> paramMap = Splitter.on("&").withKeyValueSeparator("=").split(params);
反过来,我们可能还需有将
Map
对象转化成 URL 的参数,来拼接出一个带参数的 URL。Guava 中也有非常方便的相关方法。代码如下:Map<String, String> paramMap = Maps.newHashMap(); paramMap.put("userName", "diguage"); paramMap.put("webSite", "http://www.diguage.com/"); String url = url + "?" + Joiner.on("&").withKeyValueSeparator("=").join(paramMap);
我们的项目中,使用了 Spring JdbcTemplate,并基于这个这个东东写了一个
BaseDao
,再结合注解,就可以获取表名和字段名。为了统一,规定将数据表以及字段的多个字母以下划线分割。大家都知道,Java 中类名以及属性名,都是驼峰命名法。那么就需要一个转化。 Guava 也提供了很方便的方法。代码如下:1 |
在上述代码中,
CaseFormat
中设定了几个常用的格式:LOWER_CAMEL
– 以小写字母开头的驼峰命名规则。例如:lowerCamel
。这个规则符合表示 Java 属性以及 Java 方法的命名规则。LOWER_HYPHEN
– 将单词的小写形式以连接符(-
)连接的。例如:lower-hyphen
。LOWER_UNDERSCORE
– 将单词的小写形式以连接符(_
)连接的。例如:lower_underscore
。UPPER_CAMEL
– 以大写字母开头的驼峰命名规则。例如:UpperCamel
。这个规则符合表示 Java 或 C++ 类名的命名规则。UPPER_UNDERSCORE
– 将单词的大写形式以连接符(_
)连接的。例如:UPPER_UNDERSCORE
。这个规则符合表示 Java 或 C++ 常量的命名规则。
组合使用这几个规则,可以方便地进行字符串形式的转换。例如,将上面的表名转化成类名:
1 |
最后一个问题:需要将一个当前 URL 传递到下一个请求中,方便做跳转回来。作为参数传递,肯定需要对 URL 编码,否则作为参数的 URL 的参数就可能丢失了。 Guava 中通过也可以很好的支持:
1 |
compare(a, b, Ordering.natural().nullsFirst())
return ComparisonChain.start() .compare(user.getUpdateDate(), other.getUser().getUpdateDate(), Ordering.natural().nullsLast()) .result();
https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/ComparisonChain.html
public int compareTo(Foo that) {
return ComparisonChain.start()
.compare(this.aString, that.aString)
.compare(this.anInt, that.anInt)
.compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
.result();
}
http://stackoverflow.com/questions/23615451/how-does-lists-newarraylist-of-guava-library-work
Because the compiler can infer the type from the variable declaration.
Example:
List<String> list = Lists.newArrayList(),
the compiler will understand that the type of the collection (the type of E) will be
<String>
, since you expect to get a List of String.
It was useful to avoid rewriting entire <> arguments, but with Java7 and diamond operator you can avoid it using
List<String> list = new ArrayList<>();
=
Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);
This works for up to 5 key/value pairs, otherwise you can use its builder:
Map<String, String> test = ImmutableMap.<String, String>builder()
.put("k1", "v1")
.put("k2", "v2")
...
.build();
- note that Guava's ImmutableMap implementation differs from Java's HashMap implementation (most notably it is immutable and does not permit null keys/values)
Map<String, String> transMap =
Maps.transformValues(immutableMap, new Function<Integer, String>() {
@Override
public String apply(Integer input) {
return "BTC-" + input; //new value in transformed map
}
});
Why Guava does not provide a way to transform map keys
checkArgument(count > 0, "must be positive: %s", count);
Google Guava EventBus - an Easy and Elegant Way for Your Publisher - Subscriber Use Cases
EventBus eventBus = new EventBus("test");
EventListener listener = new EventListener();
eventBus.register(listener);
// when
eventBus.post(new OurTestEvent(200));
@Subscribe
public void listen(OurTestEvent event) {
lastMessage = event.getMessage();
}
Limiting the size of InputStreams
https://stonelion.gitbooks.io/guava_ch/content/working_with_files/limiting_the_size_of_inputstreams.html
ByteSteams.limit方法使用InputStream和一个long值作为参数,并返回一个包装了的InputStream,这个InputStream只会读取与给定long值相等的byte数。
http://stackoverflow.com/questions/15445504/copy-inputstream-abort-operation-if-size-exceeds-limit
public class LimitedSizeInputStream extends InputStream {
private final InputStream original;
private final long maxSize;
private long total;
public LimitedSizeInputStream(InputStream original, long maxSize) {
this.original = original;
this.maxSize = maxSize;
}
@Override
public int read() throws IOException {
int i = original.read();
if (i>=0) incrementCounter(1);
return i;
}
@Override
public int read(byte b[]) throws IOException {
return read(b, 0, b.length);
}
@Override
public int read(byte b[], int off, int len) throws IOException {
int i = original.read(b, off, len);
if (i>=0) incrementCounter(i);
return i;
}
private void incrementCounter(int size) throws IOException {
total += size;
if (total>maxSize) throw new IOException("InputStream exceeded maximum size in bytes.");
}
}
The main difference of the implementation above with BoundedInputStream is that BoundedInputStream does not throw an exception when the limit is exceeded (it just closes the stream)Hashing a file
HashCode hashCode = Files.hash(file, Hashing.md5());
firstNonNull方法使用两个参数并且返回非空的那个参数。
String value = Objects.firstNonNull(someString,"default value");
firstNonNull 方法可以在当你并不确定对象是否是空的情况下,用于作为一种提供默认值的方式。 需要注意的是,如果两个参数都为空,那么会抛出NullPointerException错误。
新版本中Objects.firstNonNull已经是Deprecated的了,使用MoreObjects.firstNonNull(T first,T second)替换。
用于保证调用Closer.close方法时,所有注册的Closeable对象都正确的关闭。
Closer closer = Closer.create();
try{
closer.register(reader);
} catch (Throwable t) {
throw closer.rethrow(t);
} finally {
closer.close();
}
Using Preconditions
https://code.google.com/p/guava-libraries/wiki/PreconditionsExplained
https://code.google.com/p/guava-libraries/wiki/CommonObjectUtilitiesExplained
equals, hashCode
Use ComparisonChain
ComparisonChain.start().compare(this.anInt, that.anInt).compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast()).result();
Objects.toStringHelper("MyObject").add("x", 1).toString();
String: Joiner
Joiner joiner = Joiner.on("; ").skipNulls();
joiner.join("Harry", null, "Ron", "Hermione");
final Joiner.MapJoiner mapJoiner = Joiner.on('&').withKeyValueSeparator("=");
final ImmutableMap<String, String> values = ImmutableMap.of("name", "mrhaki", "worksAt", "JDriven");
assert mapJoiner.join(values).equals("name=mrhaki&worksAt=JDriven");
Splitter
Splitter.on(',').trimResults().omitEmptyStrings().split("foo,bar,, qux");
Splitter.fixedLength(8)
CharMatcher
String noControl = CharMatcher.JAVA_ISO_CONTROL.removeFrom(string); // remove control characters
String spaced = CharMatcher.WHITESPACE.trimAndCollapseFrom(string, ' ');
bytes = string.getBytes(Charsets.UTF_8);
Escapers
HtmlEscapers.htmlEscaper().escape(str)
XmlEscapers.xmlContentEscaper()/xmlAttributeEscaper().escape(str)
UrlEscapers.urlFormParameterEscaper()/urlFragmentEscaper()/urlPathSegmentEscaper()/urlFormParameterEscaper().
Net
com.google.common.net.InetAddresses.isInetAddress(String)
Collections
Google Guava RateLimiter
@ThreadSafe
javax.annotation.concurrent.ThreadSafe
* TODO(cpovirk): make SleepingStopwatch the last parameter throughout the class so that the
* overloads follow the usual convention: Foo(int), Foo(int, SleepingStopwatch)
@
WebFilter(urlPatterns
=
Array(
"/*"
))
class
RateLimiterFilter
extends
Filter {
val
limiter
=
RateLimiter.create(
100
)
def
init(filterConfig
:
FilterConfig) {}
def
doFilter(request
:
ServletRequest, response
:
ServletResponse, chain
:
FilterChain) {
if
(limiter.tryAcquire()) {
chain.doFilter(request, response)
}
else
{
response.asInstanceOf[HttpServletResponse].sendError(SC
_
TOO
_
MANY
_
REQUESTS)
}
}
def
destroy() {}
}