mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-24 18:04:54 +08:00
fix code
This commit is contained in:
parent
3e67df0d20
commit
c93c6a2b77
@ -16,6 +16,7 @@ import org.dromara.hutool.core.bean.BeanUtil;
|
||||
import org.dromara.hutool.core.codec.hash.Hash32;
|
||||
import org.dromara.hutool.core.collection.iter.IterUtil;
|
||||
import org.dromara.hutool.core.collection.iter.IteratorEnumeration;
|
||||
import org.dromara.hutool.core.collection.queue.BoundedPriorityQueue;
|
||||
import org.dromara.hutool.core.comparator.CompareUtil;
|
||||
import org.dromara.hutool.core.comparator.PinyinComparator;
|
||||
import org.dromara.hutool.core.comparator.PropertyComparator;
|
||||
|
@ -11,6 +11,7 @@
|
||||
*/
|
||||
package org.dromara.hutool.core.collection;
|
||||
|
||||
import org.dromara.hutool.core.collection.queue.CheckedLinkedBlockingQueue;
|
||||
import org.dromara.hutool.core.thread.SimpleScheduler;
|
||||
import org.dromara.hutool.core.util.RuntimeUtil;
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.collection;
|
||||
package org.dromara.hutool.core.collection.queue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
@ -10,7 +10,7 @@
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.collection;
|
||||
package org.dromara.hutool.core.collection.queue;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.collection.queue;
|
||||
|
||||
import java.util.Deque;
|
||||
|
||||
/**
|
||||
* An element that is linked on the {@link Deque}.
|
||||
*
|
||||
* @param <T> 值类型
|
||||
*/
|
||||
public interface Linked<T extends Linked<T>> {
|
||||
|
||||
/**
|
||||
* Retrieves the previous element or <tt>null</tt> if either the element is
|
||||
* unlinked or the first element on the deque.
|
||||
*
|
||||
* @return 前一个值
|
||||
*/
|
||||
T getPrevious();
|
||||
|
||||
/**
|
||||
* Sets the previous element or <tt>null</tt> if there is no link.
|
||||
*
|
||||
* @param prev 前一个值
|
||||
*/
|
||||
void setPrevious(T prev);
|
||||
|
||||
/**
|
||||
* Retrieves the next element or <tt>null</tt> if either the element is
|
||||
* unlinked or the last element on the deque.
|
||||
*
|
||||
* @return 下一个值
|
||||
*/
|
||||
T getNext();
|
||||
|
||||
/**
|
||||
* Sets the next element or <tt>null</tt> if there is no link.
|
||||
*
|
||||
* @param next 下一个值
|
||||
*/
|
||||
void setNext(T next);
|
||||
}
|
@ -0,0 +1,440 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.dromara.hutool.core.collection.queue;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Linked list implementation of the {@link Deque} interface where the link
|
||||
* pointers are tightly integrated with the element. Linked deques have no
|
||||
* capacity restrictions; they grow as necessary to support usage. They are not
|
||||
* thread-safe; in the absence of external synchronization, they do not support
|
||||
* concurrent access by multiple threads. Null elements are prohibited.
|
||||
* <p>
|
||||
* Most <tt>LinkedDeque</tt> operations run in constant time by assuming that
|
||||
* the {@link Linked} parameter is associated with the deque instance. Any usage
|
||||
* that violates this assumption will result in non-deterministic behavior.
|
||||
* <p>
|
||||
* The iterators returned by this class are <em>not</em> <i>fail-fast</i>: If
|
||||
* the deque is modified at any time after the iterator is created, the iterator
|
||||
* will be in an unknown state. Thus, in the face of concurrent modification,
|
||||
* the iterator risks arbitrary, non-deterministic behavior at an undetermined
|
||||
* time in the future.
|
||||
*
|
||||
* @param <E> the type of elements held in this collection
|
||||
* @author ben.manes@gmail.com (Ben Manes)
|
||||
* @see <a href="http://code.google.com/p/concurrentlinkedhashmap/">
|
||||
* http://code.google.com/p/concurrentlinkedhashmap/</a>
|
||||
*/
|
||||
public class LinkedDeque<E extends Linked<E>> extends AbstractCollection<E> implements Deque<E> {
|
||||
|
||||
// This class provides a doubly-linked list that is optimized for the virtual
|
||||
// machine. The first and last elements are manipulated instead of a slightly
|
||||
// more convenient sentinel element to avoid the insertion of null checks with
|
||||
// NullPointerException throws in the byte code. The links to a removed
|
||||
// element are cleared to help a generational garbage collector if the
|
||||
// discarded elements inhabit more than one generation.
|
||||
|
||||
/**
|
||||
* Pointer to first node.
|
||||
* Invariant: (first == null && last == null) ||
|
||||
* (first.prev == null)
|
||||
*/
|
||||
E first;
|
||||
|
||||
/**
|
||||
* Pointer to last node.
|
||||
* Invariant: (first == null && last == null) ||
|
||||
* (last.next == null)
|
||||
*/
|
||||
E last;
|
||||
|
||||
/**
|
||||
* Links the element to the front of the deque so that it becomes the first
|
||||
* element.
|
||||
*
|
||||
* @param e the unlinked element
|
||||
*/
|
||||
void linkFirst(final E e) {
|
||||
final E f = first;
|
||||
first = e;
|
||||
|
||||
if (f == null) {
|
||||
last = e;
|
||||
} else {
|
||||
f.setPrevious(e);
|
||||
e.setNext(f);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Links the element to the back of the deque so that it becomes the last
|
||||
* element.
|
||||
*
|
||||
* @param e the unlinked element
|
||||
*/
|
||||
void linkLast(final E e) {
|
||||
final E l = last;
|
||||
last = e;
|
||||
|
||||
if (l == null) {
|
||||
first = e;
|
||||
} else {
|
||||
l.setNext(e);
|
||||
e.setPrevious(l);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlinks the non-null first element.
|
||||
*/
|
||||
E unlinkFirst() {
|
||||
final E f = first;
|
||||
final E next = f.getNext();
|
||||
f.setNext(null);
|
||||
|
||||
first = next;
|
||||
if (next == null) {
|
||||
last = null;
|
||||
} else {
|
||||
next.setPrevious(null);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlinks the non-null last element.
|
||||
*/
|
||||
E unlinkLast() {
|
||||
final E l = last;
|
||||
final E prev = l.getPrevious();
|
||||
l.setPrevious(null);
|
||||
last = prev;
|
||||
if (prev == null) {
|
||||
first = null;
|
||||
} else {
|
||||
prev.setNext(null);
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlinks the non-null element.
|
||||
*/
|
||||
void unlink(final E e) {
|
||||
final E prev = e.getPrevious();
|
||||
final E next = e.getNext();
|
||||
|
||||
if (prev == null) {
|
||||
first = next;
|
||||
} else {
|
||||
prev.setNext(next);
|
||||
e.setPrevious(null);
|
||||
}
|
||||
|
||||
if (next == null) {
|
||||
last = prev;
|
||||
} else {
|
||||
next.setPrevious(prev);
|
||||
e.setNext(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return (first == null);
|
||||
}
|
||||
|
||||
void checkNotEmpty() {
|
||||
if (isEmpty()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* Beware that, unlike in most collections, this method is <em>NOT</em> a
|
||||
* constant-time operation.
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
int size = 0;
|
||||
for (E e = first; e != null; e = e.getNext()) {
|
||||
size++;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
for (E e = first; e != null; ) {
|
||||
final E next = e.getNext();
|
||||
e.setPrevious(null);
|
||||
e.setNext(null);
|
||||
e = next;
|
||||
}
|
||||
first = last = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(final Object o) {
|
||||
return (o instanceof Linked<?>) && contains((Linked<?>) o);
|
||||
}
|
||||
|
||||
// A fast-path containment check
|
||||
boolean contains(final Linked<?> e) {
|
||||
return (e.getPrevious() != null)
|
||||
|| (e.getNext() != null)
|
||||
|| (e == first);
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the element to the front of the deque so that it becomes the first
|
||||
* element.
|
||||
*
|
||||
* @param e the linked element
|
||||
*/
|
||||
public void moveToFront(final E e) {
|
||||
if (e != first) {
|
||||
unlink(e);
|
||||
linkFirst(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Moves the element to the back of the deque so that it becomes the last
|
||||
* element.
|
||||
*
|
||||
* @param e the linked element
|
||||
*/
|
||||
public void moveToBack(final E e) {
|
||||
if (e != last) {
|
||||
unlink(e);
|
||||
linkLast(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peek() {
|
||||
return peekFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peekFirst() {
|
||||
return first;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E peekLast() {
|
||||
return last;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getFirst() {
|
||||
checkNotEmpty();
|
||||
return peekFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E getLast() {
|
||||
checkNotEmpty();
|
||||
return peekLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E element() {
|
||||
return getFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offer(final E e) {
|
||||
return offerLast(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offerFirst(final E e) {
|
||||
if (contains(e)) {
|
||||
return false;
|
||||
}
|
||||
linkFirst(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean offerLast(final E e) {
|
||||
if (contains(e)) {
|
||||
return false;
|
||||
}
|
||||
linkLast(e);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(final E e) {
|
||||
return offerLast(e);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addFirst(final E e) {
|
||||
if (!offerFirst(e)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLast(final E e) {
|
||||
if (!offerLast(e)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public E poll() {
|
||||
return pollFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pollFirst() {
|
||||
return isEmpty() ? null : unlinkFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pollLast() {
|
||||
return isEmpty() ? null : unlinkLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public E remove() {
|
||||
return removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public boolean remove(final Object o) {
|
||||
return (o instanceof Linked<?>) && remove((E) o);
|
||||
}
|
||||
|
||||
// A fast-path removal
|
||||
boolean remove(final E e) {
|
||||
if (contains(e)) {
|
||||
unlink(e);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeFirst() {
|
||||
checkNotEmpty();
|
||||
return pollFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeFirstOccurrence(final Object o) {
|
||||
return remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E removeLast() {
|
||||
checkNotEmpty();
|
||||
return pollLast();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLastOccurrence(final Object o) {
|
||||
return remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(final Collection<?> c) {
|
||||
boolean modified = false;
|
||||
for (final Object o : c) {
|
||||
modified |= remove(o);
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void push(final E e) {
|
||||
addFirst(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E pop() {
|
||||
return removeFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> iterator() {
|
||||
return new AbstractLinkedIterator(first) {
|
||||
@Override
|
||||
E computeNext() {
|
||||
return cursor.getNext();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<E> descendingIterator() {
|
||||
return new AbstractLinkedIterator(last) {
|
||||
@Override
|
||||
E computeNext() {
|
||||
return cursor.getPrevious();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
abstract class AbstractLinkedIterator implements Iterator<E> {
|
||||
E cursor;
|
||||
|
||||
/**
|
||||
* Creates an iterator that can can traverse the deque.
|
||||
*
|
||||
* @param start the initial element to begin traversal from
|
||||
*/
|
||||
AbstractLinkedIterator(final E start) {
|
||||
cursor = start;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return (cursor != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public E next() {
|
||||
if (!hasNext()) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
final E e = cursor;
|
||||
cursor = computeNext();
|
||||
return e;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the next element to traverse to or <tt>null</tt> if there are
|
||||
* no more elements.
|
||||
*/
|
||||
abstract E computeNext();
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2023 looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* http://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 队列{@link java.util.Queue}相关封装
|
||||
*/
|
||||
package org.dromara.hutool.core.collection.queue;
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2012 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.dromara.hutool.core.map.concurrent;
|
||||
|
||||
/**
|
||||
* A class that can determine the weight of an entry. The total weight threshold
|
||||
* is used to determine when an eviction is required.
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @author ben.manes@gmail.com (Ben Manes)
|
||||
* @see <a href="http://code.google.com/p/concurrentlinkedhashmap/">
|
||||
* http://code.google.com/p/concurrentlinkedhashmap/</a>
|
||||
*/
|
||||
public interface EntryWeigher<K, V> {
|
||||
|
||||
/**
|
||||
* Measures an entry's weight to determine how many units of capacity that
|
||||
* the key and value consumes. An entry must consume a minimum of one unit.
|
||||
*
|
||||
* @param key the key to weigh
|
||||
* @param value the value to weigh
|
||||
* @return the entry's weight
|
||||
*/
|
||||
int weightOf(K key, V value);
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.dromara.hutool.core.map.concurrent;
|
||||
|
||||
/**
|
||||
* A class that can determine the weight of a value. The total weight threshold
|
||||
* is used to determine when an eviction is required.
|
||||
*
|
||||
* @param <V> 值类型
|
||||
* @author ben.manes@gmail.com (Ben Manes)
|
||||
* @see <a href="http://code.google.com/p/concurrentlinkedhashmap/">
|
||||
* http://code.google.com/p/concurrentlinkedhashmap/</a>
|
||||
*/
|
||||
public interface Weigher<V> {
|
||||
|
||||
/**
|
||||
* Measures an object's weight to determine how many units of capacity that
|
||||
* the value consumes. A value must consume a minimum of one unit.
|
||||
*
|
||||
* @param value the object to weigh
|
||||
* @return the object's weight
|
||||
*/
|
||||
int weightOf(V value);
|
||||
}
|
288
hutool-core/src/main/java/org/dromara/hutool/core/map/concurrent/Weighers.java
Executable file
288
hutool-core/src/main/java/org/dromara/hutool/core/map/concurrent/Weighers.java
Executable file
@ -0,0 +1,288 @@
|
||||
/*
|
||||
* Copyright 2010 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.dromara.hutool.core.map.concurrent;
|
||||
|
||||
import org.dromara.hutool.core.collection.iter.IterUtil;
|
||||
import org.dromara.hutool.core.lang.Assert;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A common set of {@link Weigher} and {@link EntryWeigher} implementations.
|
||||
*
|
||||
* @author ben.manes@gmail.com (Ben Manes)
|
||||
* @see <a href="http://code.google.com/p/concurrentlinkedhashmap/">
|
||||
* http://code.google.com/p/concurrentlinkedhashmap/</a>
|
||||
*/
|
||||
public final class Weighers {
|
||||
|
||||
private Weighers() {
|
||||
throw new AssertionError();
|
||||
}
|
||||
|
||||
/**
|
||||
* A entry weigher backed by the specified weigher. The weight of the value
|
||||
* determines the weight of the entry.
|
||||
*
|
||||
* @param weigher the weigher to be "wrapped" in a entry weigher.
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @return A entry weigher view of the specified weigher.
|
||||
*/
|
||||
public static <K, V> EntryWeigher<K, V> asEntryWeigher(
|
||||
final Weigher<? super V> weigher) {
|
||||
return (weigher == singleton())
|
||||
? Weighers.<K, V>entrySingleton()
|
||||
: new EntryWeigherView<K, V>(weigher);
|
||||
}
|
||||
|
||||
/**
|
||||
* A weigher where an entry has a weight of <tt>1</tt>. A map bounded with
|
||||
* this weigher will evict when the number of key-value pairs exceeds the
|
||||
* capacity.
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @return A weigher where a value takes one unit of capacity.
|
||||
*/
|
||||
@SuppressWarnings({"cast", "unchecked"})
|
||||
public static <K, V> EntryWeigher<K, V> entrySingleton() {
|
||||
return (EntryWeigher<K, V>) SingletonEntryWeigher.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* A weigher where a value has a weight of <tt>1</tt>. A map bounded with
|
||||
* this weigher will evict when the number of key-value pairs exceeds the
|
||||
* capacity.
|
||||
*
|
||||
* @param <V> 值类型
|
||||
* @return A weigher where a value takes one unit of capacity.
|
||||
*/
|
||||
@SuppressWarnings({"cast", "unchecked"})
|
||||
public static <V> Weigher<V> singleton() {
|
||||
return (Weigher<V>) SingletonWeigher.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* A weigher where the value is a byte array and its weight is the number of
|
||||
* bytes. A map bounded with this weigher will evict when the number of bytes
|
||||
* exceeds the capacity rather than the number of key-value pairs in the map.
|
||||
* This allows for restricting the capacity based on the memory-consumption
|
||||
* and is primarily for usage by dedicated caching servers that hold the
|
||||
* serialized data.
|
||||
* <p>
|
||||
* A value with a weight of <tt>0</tt> will be rejected by the map. If a value
|
||||
* with this weight can occur then the caller should eagerly evaluate the
|
||||
* value and treat it as a removal operation. Alternatively, a custom weigher
|
||||
* may be specified on the map to assign an empty value a positive weight.
|
||||
*
|
||||
* @return A weigher where each byte takes one unit of capacity.
|
||||
*/
|
||||
public static Weigher<byte[]> byteArray() {
|
||||
return ByteArrayWeigher.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* A weigher where the value is a {@link Iterable} and its weight is the
|
||||
* number of elements. This weigher only should be used when the alternative
|
||||
* {@link #collection()} weigher cannot be, as evaluation takes O(n) time. A
|
||||
* map bounded with this weigher will evict when the total number of elements
|
||||
* exceeds the capacity rather than the number of key-value pairs in the map.
|
||||
* <p>
|
||||
* A value with a weight of <tt>0</tt> will be rejected by the map. If a value
|
||||
* with this weight can occur then the caller should eagerly evaluate the
|
||||
* value and treat it as a removal operation. Alternatively, a custom weigher
|
||||
* may be specified on the map to assign an empty value a positive weight.
|
||||
*
|
||||
* @param <E> 元素类型
|
||||
* @return A weigher where each element takes one unit of capacity.
|
||||
*/
|
||||
@SuppressWarnings({"cast", "unchecked"})
|
||||
public static <E> Weigher<? super Iterable<E>> iterable() {
|
||||
return (Weigher<Iterable<E>>) (Weigher<?>) IterableWeigher.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* A weigher where the value is a {@link Collection} and its weight is the
|
||||
* number of elements. A map bounded with this weigher will evict when the
|
||||
* total number of elements exceeds the capacity rather than the number of
|
||||
* key-value pairs in the map.
|
||||
* <p>
|
||||
* A value with a weight of <tt>0</tt> will be rejected by the map. If a value
|
||||
* with this weight can occur then the caller should eagerly evaluate the
|
||||
* value and treat it as a removal operation. Alternatively, a custom weigher
|
||||
* may be specified on the map to assign an empty value a positive weight.
|
||||
*
|
||||
* @param <E> 元素类型
|
||||
* @return A weigher where each element takes one unit of capacity.
|
||||
*/
|
||||
@SuppressWarnings({"cast", "unchecked"})
|
||||
public static <E> Weigher<? super Collection<E>> collection() {
|
||||
return (Weigher<Collection<E>>) (Weigher<?>) CollectionWeigher.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* A weigher where the value is a {@link List} and its weight is the number
|
||||
* of elements. A map bounded with this weigher will evict when the total
|
||||
* number of elements exceeds the capacity rather than the number of
|
||||
* key-value pairs in the map.
|
||||
* <p>
|
||||
* A value with a weight of <tt>0</tt> will be rejected by the map. If a value
|
||||
* with this weight can occur then the caller should eagerly evaluate the
|
||||
* value and treat it as a removal operation. Alternatively, a custom weigher
|
||||
* may be specified on the map to assign an empty value a positive weight.
|
||||
*
|
||||
* @param <E> 元素类型
|
||||
* @return A weigher where each element takes one unit of capacity.
|
||||
*/
|
||||
@SuppressWarnings({"cast"})
|
||||
public static <E> Weigher<? super List<E>> list() {
|
||||
return ListWeigher.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* A weigher where the value is a {@link Set} and its weight is the number
|
||||
* of elements. A map bounded with this weigher will evict when the total
|
||||
* number of elements exceeds the capacity rather than the number of
|
||||
* key-value pairs in the map.
|
||||
* <p>
|
||||
* A value with a weight of <tt>0</tt> will be rejected by the map. If a value
|
||||
* with this weight can occur then the caller should eagerly evaluate the
|
||||
* value and treat it as a removal operation. Alternatively, a custom weigher
|
||||
* may be specified on the map to assign an empty value a positive weight.
|
||||
*
|
||||
* @param <E> 元素类型
|
||||
* @return A weigher where each element takes one unit of capacity.
|
||||
*/
|
||||
@SuppressWarnings({"cast"})
|
||||
public static <E> Weigher<? super Set<E>> set() {
|
||||
return SetWeigher.INSTANCE;
|
||||
}
|
||||
|
||||
/**
|
||||
* A weigher where the value is a {@link Map} and its weight is the number of
|
||||
* entries. A map bounded with this weigher will evict when the total number of
|
||||
* entries across all values exceeds the capacity rather than the number of
|
||||
* key-value pairs in the map.
|
||||
* <p>
|
||||
* A value with a weight of <tt>0</tt> will be rejected by the map. If a value
|
||||
* with this weight can occur then the caller should eagerly evaluate the
|
||||
* value and treat it as a removal operation. Alternatively, a custom weigher
|
||||
* may be specified on the map to assign an empty value a positive weight.
|
||||
*
|
||||
* @param <K> 键类型
|
||||
* @param <V> 值类型
|
||||
* @return A weigher where each entry takes one unit of capacity.
|
||||
*/
|
||||
@SuppressWarnings({"cast"})
|
||||
public static <K, V> Weigher<? super Map<K, V>> map() {
|
||||
return MapWeigher.INSTANCE;
|
||||
}
|
||||
|
||||
static final class EntryWeigherView<K, V> implements EntryWeigher<K, V>, Serializable {
|
||||
private static final long serialVersionUID = 1;
|
||||
final Weigher<? super V> weigher;
|
||||
|
||||
EntryWeigherView(final Weigher<? super V> weigher) {
|
||||
Assert.notNull(weigher);
|
||||
this.weigher = weigher;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int weightOf(final K key, final V value) {
|
||||
return weigher.weightOf(value);
|
||||
}
|
||||
}
|
||||
|
||||
enum SingletonEntryWeigher implements EntryWeigher<Object, Object> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int weightOf(final Object key, final Object value) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
enum SingletonWeigher implements Weigher<Object> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int weightOf(final Object value) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
enum ByteArrayWeigher implements Weigher<byte[]> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int weightOf(final byte[] value) {
|
||||
return value.length;
|
||||
}
|
||||
}
|
||||
|
||||
enum IterableWeigher implements Weigher<Iterable<?>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int weightOf(final Iterable<?> values) {
|
||||
if (values instanceof Collection<?>) {
|
||||
return ((Collection<?>) values).size();
|
||||
}
|
||||
return IterUtil.size(values);
|
||||
}
|
||||
}
|
||||
|
||||
enum CollectionWeigher implements Weigher<Collection<?>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int weightOf(final Collection<?> values) {
|
||||
return values.size();
|
||||
}
|
||||
}
|
||||
|
||||
enum ListWeigher implements Weigher<List<?>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int weightOf(final List<?> values) {
|
||||
return values.size();
|
||||
}
|
||||
}
|
||||
|
||||
enum SetWeigher implements Weigher<Set<?>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int weightOf(final Set<?> values) {
|
||||
return values.size();
|
||||
}
|
||||
}
|
||||
|
||||
enum MapWeigher implements Weigher<Map<?, ?>> {
|
||||
INSTANCE;
|
||||
|
||||
@Override
|
||||
public int weightOf(final Map<?, ?> values) {
|
||||
return values.size();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* This package contains an implementation of a bounded
|
||||
* {@link java.util.concurrent.ConcurrentMap} data structure.
|
||||
* <p>
|
||||
* {@link com.googlecode.concurrentlinkedhashmap.Weigher} is a simple interface
|
||||
* for determining how many units of capacity an entry consumes. Depending on
|
||||
* which concrete Weigher class is used, an entry may consume a different amount
|
||||
* of space within the cache. The
|
||||
* {@link com.googlecode.concurrentlinkedhashmap.Weighers} class provides
|
||||
* utility methods for obtaining the most common kinds of implementations.
|
||||
* <p>
|
||||
* {@link com.googlecode.concurrentlinkedhashmap.EvictionListener} provides the
|
||||
* ability to be notified when an entry is evicted from the map. An eviction
|
||||
* occurs when the entry was automatically removed due to the map exceeding a
|
||||
* capacity threshold. It is not called when an entry was explicitly removed.
|
||||
* <p>
|
||||
* The {@link com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap}
|
||||
* class supplies an efficient, scalable, thread-safe, bounded map. As with the
|
||||
* <tt>Java Collections Framework</tt> the "Concurrent" prefix is used to
|
||||
* indicate that the map is not governed by a single exclusion lock.
|
||||
*
|
||||
* @see <a href="http://code.google.com/p/concurrentlinkedhashmap/">
|
||||
* http://code.google.com/p/concurrentlinkedhashmap/</a>
|
||||
*/
|
||||
package org.dromara.hutool.core.map.concurrent;
|
@ -8,7 +8,7 @@ public class ClassLoaderUtilTest {
|
||||
|
||||
@Test
|
||||
public void isPresentTest() {
|
||||
final boolean present = ClassLoaderUtil.isPresent("classloader.org.dromara.hutool.core.ClassLoaderUtil");
|
||||
final boolean present = ClassLoaderUtil.isPresent("org.dromara.hutool.core.classloader.ClassLoaderUtil");
|
||||
Assertions.assertTrue(present);
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ public class ConvertTest {
|
||||
|
||||
@Test
|
||||
public void toClassTest(){
|
||||
final Class<?> convert = Convert.convert(Class.class, "convert.org.dromara.hutool.core.ConvertTest.Product");
|
||||
final Class<?> convert = Convert.convert(Class.class, "org.dromara.hutool.core.convert.ConvertTest.Product");
|
||||
Assertions.assertSame(Product.class, convert);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,6 @@ public class CallerUtilTest {
|
||||
Assertions.assertEquals("getCallerMethodNameTest", callerMethodName);
|
||||
|
||||
final String fullCallerMethodName = CallerUtil.getCallerMethodName(true);
|
||||
Assertions.assertEquals("caller.lang.org.dromara.hutool.core.CallerUtilTest.getCallerMethodNameTest", fullCallerMethodName);
|
||||
Assertions.assertEquals("org.dromara.hutool.core.lang.caller.CallerUtilTest.getCallerMethodNameTest", fullCallerMethodName);
|
||||
}
|
||||
}
|
||||
|
@ -149,11 +149,11 @@ public class MethodUtilTest {
|
||||
Assertions.assertEquals(3, methods.length);
|
||||
|
||||
// getA属于本类
|
||||
Assertions.assertEquals("public void reflect.org.dromara.hutool.core.ReflectUtilTest$C2.getA()", methods[0].toString());
|
||||
Assertions.assertEquals("public void org.dromara.hutool.core.reflect.ReflectUtilTest$C2.getA()", methods[0].toString());
|
||||
// getB属于父类
|
||||
Assertions.assertEquals("public void reflect.org.dromara.hutool.core.ReflectUtilTest$C1.getB()", methods[1].toString());
|
||||
Assertions.assertEquals("public void org.dromara.hutool.core.reflect.ReflectUtilTest$C1.getB()", methods[1].toString());
|
||||
// getC属于接口中的默认方法
|
||||
Assertions.assertEquals("public default void reflect.org.dromara.hutool.core.ReflectUtilTest$TestInterface1.getC()", methods[2].toString());
|
||||
Assertions.assertEquals("public default void org.dromara.hutool.core.reflect.ReflectUtilTest$TestInterface1.getC()", methods[2].toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -17,7 +17,7 @@ public class ClassUtilTest {
|
||||
@Test
|
||||
public void getClassNameTest() {
|
||||
final String className = ClassUtil.getClassName(ClassUtil.class, false);
|
||||
Assertions.assertEquals("reflect.org.dromara.hutool.core.ClassUtil", className);
|
||||
Assertions.assertEquals("org.dromara.hutool.core.reflect.ClassUtil", className);
|
||||
|
||||
final String simpleClassName = ClassUtil.getClassName(ClassUtil.class, true);
|
||||
Assertions.assertEquals("ClassUtil", simpleClassName);
|
||||
@ -31,9 +31,9 @@ public class ClassUtilTest {
|
||||
|
||||
@Test
|
||||
public void getShortClassNameTest() {
|
||||
final String className = "text.org.dromara.hutool.core.StrUtil";
|
||||
final String className = "org.dromara.hutool.core.text.StrUtil";
|
||||
final String result = ClassUtil.getShortClassName(className);
|
||||
Assertions.assertEquals("c.h.c.t.StrUtil", result);
|
||||
Assertions.assertEquals("o.d.h.c.t.StrUtil", result);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -119,7 +119,7 @@ public class JetbrickEngine implements TemplateEngine {
|
||||
props.setProperty("$loader.root", config.getPath());
|
||||
break;
|
||||
case STRING:
|
||||
props.setProperty("$loader", "loader.jetbrick.engine.template.org.dromara.hutool.extra.StringResourceLoader");
|
||||
props.setProperty("$loader", "org.dromara.hutool.extra.template.engine.jetbrick.loader.StringResourceLoader");
|
||||
props.setProperty("$loader.charset", config.getCharsetStr());
|
||||
break;
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user