- Stream API
Comparator<Integer> com = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
TreeSet<Integer> treeSet = new TreeSet<>(com);
@Test
public void test1(){
Comparator<Integer> com = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1, o2);
}
};
TreeSet<Integer> treeSet = new TreeSet<>(com);
}
return Integer.compare(o1, o2);
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
TreeSet<Integer> treeSet = new TreeSet<>((x, y) -> Integer.compare(x, y));
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
private static final long serialVersionUID = -9079722457749166858L;
private String name;
private Integer age;
private Double salary;
}
protected List<Employee> employees = Arrays.asList(
new Employee("张三", 18, 9999.99),
new Employee("李四", 38, 5555.55),
new Employee("王五", 60, 6666.66),
new Employee("赵六", 16, 7777.77),
new Employee("田七", 18, 3333.33)
);
public List<Employee> filterEmployeesByAge(List<Employee> list){
List<Employee> employees = new ArrayList<>();
for(Employee e : list){
if(e.getAge() >= 30){
employees.add(e);
}
}
return employees;
}
@Test
public void test3(){
List<Employee> employeeList = filterEmployeesByAge(this.employees);
for (Employee e : employeeList){
System.out.println(e);
}
}
Employee(name=李四, age=38, salary=5555.55)
Employee(name=王五, age=60, salary=6666.66)
public List<Employee> filterEmployeesBySalary(List<Employee> list){
List<Employee> employees = new ArrayList<>();
for(Employee e : list){
if(e.getSalary() >= 5000){
employees.add(e);
}
}
return employees;
}
public interface MyPredicate<T> {
/**
* 对传递过来的T类型的数据进行过滤
* 符合规则返回true,不符合规则返回false
*/
boolean filter(T t);
}
public class FilterEmployeeByAge implements MyPredicate<Employee> {
@Override
public boolean filter(Employee employee) {
return employee.getAge() >= 30;
}
}
//优化方式一
public List<Employee> filterEmployee(List<Employee> list, MyPredicate<Employee> myPredicate){
List<Employee> employees = new ArrayList<>();
for(Employee e : list){
if(myPredicate.filter(e)){
employees.add(e);
}
}
return employees;
}
@Test
public void test4(){
List<Employee> employeeList = this.filterEmployee(this.employees, new FilterEmployeeByAge());
for (Employee e : employeeList){
System.out.println(e);
}
}
Employee(name=李四, age=38, salary=5555.55)
Employee(name=王五, age=60, salary=6666.66)
public class FilterEmployeeBySalary implements MyPredicate<Employee>{
@Override
public boolean filter(Employee employee) {
return employee.getSalary() >= 5000;
}
}
@Test
public void test5(){
List<Employee> employeeList = this.filterEmployee(this.employees, new FilterEmployeeBySalary());
for (Employee e : employeeList){
System.out.println(e);
}
}
Employee(name=张三, age=18, salary=9999.99)
Employee(name=李四, age=38, salary=5555.55)
Employee(name=王五, age=60, salary=6666.66)
Employee(name=赵六, age=16, salary=7777.77)
@Test
public void test6(){
List<Employee> employeeList = this.filterEmployee(this.employees, new MyPredicate<Employee>() {
@Override
public boolean filter(Employee employee) {
return employee.getAge() >= 30;
}
});
for (Employee e : employeeList){
System.out.println(e);
}
}
Employee(name=李四, age=38, salary=5555.55)
Employee(name=王五, age=60, salary=6666.66)
@Test
public void test7(){
List<Employee> employeeList = this.filterEmployee(this.employees, new MyPredicate<Employee>() {
@Override
public boolean filter(Employee employee) {
return employee.getSalary() >= 5000;
}
});
for (Employee e : employeeList){
System.out.println(e);
}
}
Employee(name=张三, age=18, salary=9999.99)
Employee(name=李四, age=38, salary=5555.55)
Employee(name=王五, age=60, salary=6666.66)
Employee(name=赵六, age=16, salary=7777.77)
@Test
public void test8(){
filterEmployee(this.employees, (e) -> e.getAge() >= 30).forEach(System.out::println);
}
Employee(name=李四, age=38, salary=5555.55)
Employee(name=王五, age=60, salary=6666.66)
@Test
public void test9(){
filterEmployee(this.employees, (e) -> e.getSalary() >= 5000).forEach(System.out::println);
}
Employee(name=张三, age=18, salary=9999.99)
Employee(name=李四, age=38, salary=5555.55)
Employee(name=王五, age=60, salary=6666.66)
Employee(name=赵六, age=16, salary=7777.77)
@Test
public void test10(){
employees.stream().filter((e) -> e.getSalary() >= 5000).forEach(System.out::println);
}
Employee(name=张三, age=18, salary=9999.99)
Employee(name=李四, age=38, salary=5555.55)
Employee(name=王五, age=60, salary=6666.66)
Employee(name=赵六, age=16, salary=7777.77)
@Test
public void test11(){
employees.stream().filter((e) -> e.getSalary() >= 5000).limit(2).forEach(System.out::println);
}
Employee(name=张三, age=18, salary=9999.99)
Employee(name=李四, age=38, salary=5555.55)
@Test
public void test12(){
employees.stream().filter((e) -> e.getSalary() >= 5000).map(Employee::getName).forEach(System.out::println);
}
张三
李四
王五
赵六
Runnable r = new Runnable(){
@Override
public void run(){
System.out.println("Hello Lambda");
}
}
Runnable r = () -> System.out.println("Hello Lambda");
TreeSet<Integer> ts = new TreeSet<>(new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2){
return Integer.compare(o1, o2);
}
});
TreeSet<Integer> ts = new TreeSet<>(
(o1, o2) -> Integer.compare(o1, o2);
);
Runnable r = () -> System.out.println("Hello Lambda");
@Test
public void test1(){
Runnable r = () -> System.out.println("Hello Lambda");
new Thread(r).start();
}
Consumer<String> func = (s) -> System.out.println(s);
@Test
public void test2(){
Consumer<String> consumer = (x) -> System.out.println(x);
consumer.accept("Hello Lambda");
}
Consumer<String> func = s -> System.out.println(s);
@Test
public void test3(){
Consumer<String> consumer = x -> System.out.println(x);
consumer.accept("Hello Lambda");
}
BinaryOperator<Integer> bo = (a, b) -> {
System.out.println("函数式接口");
return a + b;
};
@Test
public void test4(){
Comparator<Integer> comparator = (x, y) -> {
System.out.println("函数式接口");
return Integer.compare(x, y);
};
}
BinaryOperator<Integer> bo = (a, b) -> a + b;
@Test
public void test5(){
Comparator<Integer> comparator = (x, y) -> Integer.compare(x, y);
}
BinaryOperator<Integer> bo = (Integer a, Integer b) -> {
return a + b;
};
BinaryOperator<Integer> bo = (a, b) -> {
return a + b;
};
@FunctionalInterface
public interface MyFunc <T> {
public T getValue(T t);
}
public String handlerString(MyFunc<String> myFunc, String str){
return myFunc.getValue(str);
}
@Test
public void test6(){
String str = handlerString((s) -> s.toUpperCase(), "binghe");
System.out.println(str);
}
BINGHE
@Test
public void test7(){
String str = handlerString((s) -> s.substring(0,4), "binghe");
System.out.println(str);
}
bing
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
private static final long serialVersionUID = -9079722457749166858L;
private String name;
private Integer age;
private Double salary;
}
protected List<Employee> employees = Arrays.asList(
new Employee("张三", 18, 9999.99),
new Employee("李四", 38, 5555.55),
new Employee("王五", 60, 6666.66),
new Employee("赵六", 8, 7777.77),
new Employee("田七", 58, 3333.33)
);
@Test
public void test1(){
Collections.sort(employees, (e1, e2) -> {
if(e1.getAge() == e2.getAge()){
return e1.getName().compareTo(e2.getName());
}
return Integer.compare(e1.getAge(), e2.getAge());
});
employees.stream().forEach(System.out::println);
}
Employee(name=赵六, age=8, salary=7777.77)
Employee(name=张三, age=18, salary=9999.99)
Employee(name=李四, age=38, salary=5555.55)
Employee(name=田七, age=58, salary=3333.33)
Employee(name=王五, age=60, salary=6666.66)
@Test
public void test1(){
Collections.sort(employees, (e1, e2) -> {
if(e1.getAge() == e2.getAge()){
return e1.getName().compareTo(e2.getName());
}
return -Integer.compare(e1.getAge(), e2.getAge());
});
employees.stream().forEach(System.out::println);
}
Employee(name=王五, age=60, salary=6666.66)
Employee(name=田七, age=58, salary=3333.33)
Employee(name=李四, age=38, salary=5555.55)
Employee(name=张三, age=18, salary=9999.99)
Employee(name=赵六, age=8, salary=7777.77)
@FunctionalInterface
public interface MyFunction {
public String getValue(String str);
}
public String stringHandler(String str, MyFunction myFunction){
return myFunction.getValue(str);
}
@Test
public void test2(){
String value = stringHandler("binghe", (s) -> s.toUpperCase());
System.out.println(value);
}
BINGHE
@Test
public void test3(){
String value = stringHandler("binghe", (s) -> s.substring(1, 3));
System.out.println(value);
}
in
@FunctionalInterface
public interface MyFunc<T, R> {
R getValue(T t1, T t2);
}
public void operate(Long num1, Long num2, MyFunc<Long, Long> myFunc){
System.out.println(myFunc.getValue(num1, num2));
}
@Test
public void test4(){
operate(100L, 200L, (x, y) -> x + y);
}
300
@Test
public void test5(){
operate(100L, 200L, (x, y) -> x * y);
}
20000
T | void | ||
T | |||
T | R | ||
T | boolean |
BiFunction(T, U, R) | T, U | R | |
T | T | ||
T, T | T | ||
BiConsumer<T, U> | T, U | void | |
ToIntFunction<T> | T | int | |
ToLongFunction<T> | T | long | |
ToDoubleFunction<T> | T | double | |
IntFunction<R> | int | R | |
LongFunction<R> | long | R | |
DoubleFunction<R> | double | R |
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
public void handlerConsumer(Integer number, Consumer<Integer> consumer){
consumer.accept(number);
}
@Test
public void test1(){
this.handlerConsumer(10000, (i) -> System.out.println(i));
}
@FunctionalInterface
public interface Supplier<T> {
T get();
}
public List<Integer> getNumberList(int num, Supplier<Integer> supplier){
List<Integer> list = new ArrayList<>();
for(int i = 0; i < num; i++){
list.add(supplier.get())
}
return list;
}
@Test
public void test2(){
List<Integer> numberList = this.getNumberList(10, () -> new Random().nextInt(100));
numberList.stream().forEach(System.out::println);
}
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
public String handlerString(String str, Function<String, String> func){
return func.apply(str);
}
@Test
public void test3(){
String str = this.handlerString("binghe", (s) -> s.toUpperCase());
System.out.println(str);
}
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
public List<String> filterString(List<String> list, Predicate<String> predicate){
List<String> strList = new ArrayList<>();
for(String str : list){
if(predicate.test(str)){
strList.add(str);
}
}
return strList;
}
@Test
public void test4(){
List<String> list = Arrays.asList("Hello", "Lambda", "binghe", "lyz", "World");
List<String> strList = this.filterString(list, (s) -> s.length() >= 5);
strList.stream().forEach(System.out::println);
}
(x) -> System.out.println(x);
System.out::println
BinaryOperator<Double> bo = (x, y) -> Math.pow(x, y);
BinaryOperator<Double> bo = Math::pow;
compare((x, y) -> x.equals(y), "binghe", "binghe")
compare(String::equals, "binghe", "binghe")
ClassName::new
Function<Integer, MyClass> fun = (n) -> new MyClass(n);
Function<Integer, MyClass> fun = MyClass::new;
type[]::new
Function<Integer, Integer[]> fun = (n) -> new Integer[n];
Function<Integer, Integer[]> fun = Integer[]::new;
- public static IntStream stream(int[] array)
- public static LongStream stream(long[] array)
- public static DoubleStream stream(double[] array)
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
public static<T> Stream<T> generate(Supplier<T> s)
default Stream<E> stream() {
return StreamSupport.stream(spliterator(), false);
}
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
List<String> list = new ArrayList<>();
list.stream();
list.parallelStream();
public static <T> Stream<T> stream(T[] array) {
return stream(array, 0, array.length);
}
public static <T> Stream<T> stream(T[] array) {
return stream(array, 0, array.length);
}
public static <T> Stream<T> stream(T[] array, int startInclusive, int endExclusive) {
return StreamSupport.stream(spliterator(array, startInclusive, endExclusive), false);
}
public static IntStream stream(int[] array) {
return stream(array, 0, array.length);
}
public static IntStream stream(int[] array, int startInclusive, int endExclusive) {
return StreamSupport.intStream(spliterator(array, startInclusive, endExclusive), false);
}
public static LongStream stream(long[] array) {
return stream(array, 0, array.length);
}
public static LongStream stream(long[] array, int startInclusive, int endExclusive) {
return StreamSupport.longStream(spliterator(array, startInclusive, endExclusive), false);
}
public static DoubleStream stream(double[] array) {
return stream(array, 0, array.length);
}
public static DoubleStream stream(double[] array, int startInclusive, int endExclusive) {
return StreamSupport.doubleStream(spliterator(array, startInclusive, endExclusive), false);
}
Integer[] nums = new Integer[]{1,2,3,4,5,6,7,8,9};
Stream<Integer> numStream = Arrays.stream(nums);
public static<T> Stream<T> of(T t) {
return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}
@SafeVarargs
@SuppressWarnings("varargs")
public static<T> Stream<T> of(T... values) {
return Arrays.stream(values);
}
Stream<String> strStream = Stream.of("a", "b", "c");
public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
Objects.requireNonNull(f);
final Iterator<T> iterator = new Iterator<T>() {
@SuppressWarnings("unchecked")
T t = (T) Streams.NONE;
@Override
public boolean hasNext() {
return true;
}
@Override
public T next() {
return t = (t == Streams.NONE) ? seed : f.apply(t);
}
};
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
}
public static<T> Stream<T> generate(Supplier<T> s) {
Objects.requireNonNull(s);
return StreamSupport.stream(
new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s), false);
}
Stream<Integer> intStream = Stream.iterate(0, (x) -> x + 2);
intStream.forEach(System.out::println);
Stream<Integer> intStream = Stream.iterate(0, (x) -> x + 2);
intStream.limit(10).forEach(System.out::println);
Stream.generate(() -> Math.random()).forEach(System.out::println);
Stream.generate(() -> Math.random()).limit(5).forEach(System.out::println);
public static<T> Stream<T> empty() {
return StreamSupport.stream(Spliterators.<T>emptySpliterator(), false);
}
Stream<String> empty = Stream.empty();
filter(Predicate p) | |
distinct() | |
limit(long maxSize) | |
skip(long n) |
protected List<Employee> list = Arrays.asList(
new Employee("张三", 18, 9999.99),
new Employee("李四", 38, 5555.55),
new Employee("王五", 60, 6666.66),
new Employee("赵六", 8, 7777.77),
new Employee("田七", 58, 3333.33)
);
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
private static final long serialVersionUID = -9079722457749166858L;
private String name;
private Integer age;
private Double salary;
}
Stream<T> filter(Predicate<? super T> predicate);
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
default Predicate<T> and(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) && other.test(t);
}
default Predicate<T> negate() {
return (t) -> !test(t);
}
default Predicate<T> or(Predicate<? super T> other) {
Objects.requireNonNull(other);
return (t) -> test(t) || other.test(t);
}
static <T> Predicate<T> isEqual(Object targetRef) {
return (null == targetRef)
? Objects::isNull
: object -> targetRef.equals(object);
}
}
//内部迭代:在此过程中没有进行过迭代,由Stream api进行迭代
//中间操作:不会执行任何操作
Stream<Person> stream = list.stream().filter((e) -> {
System.out.println("Stream API 中间操作");
return e.getAge() > 30;
});
//外部迭代
Iterator<Person> it = list.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
Stream<T> limit(long maxSize);
//过滤之后取2个值
list.stream().filter((e) -> e.getAge() >30 ).limit(2).forEach(System.out :: println);
Stream<T> skip(long n);
//跳过前2个值
list.stream().skip(2).forEach(System.out :: println);
Stream<T> distinct();
list.stream().distinct().forEach(System.out :: println);
map(Function f) | |
mapToDouble(ToDoubleFunction f) | |
mapToInt(ToIntFunction f) | |
mapToLong(ToLongFunction f) | |
flatMap(Function f) |
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
//将流中每一个元素都映射到map的函数中,每个元素执行这个函数,再返回
List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
list.stream().map((e) -> e.toUpperCase()).forEach(System.out::printf);
//获取Person中的每一个人得名字name,再返回一个集合
List<String> names = this.list.stream().map(Person :: getName).collect(Collectors.toList());
2.flatMap()
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper);
/**
* flatMap —— 接收一个函数作为参数,将流中的每个值都换成一个流,然后把所有流连接成一个流
*/
@Test
public void testFlatMap () {
StreamAPI_Test s = new StreamAPI_Test();
List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");
list.stream().flatMap((e) -> s.filterCharacter(e)).forEach(System.out::println);
//如果使用map则需要这样写
list.stream().map((e) -> s.filterCharacter(e)).forEach((e) -> {
e.forEach(System.out::println);
});
}
/**
* 将一个字符串转换为流
*/
public Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
sorted() | |
sorted(Comparator comp) |
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
// 自然排序
List<Employee> persons = list.stream().sorted().collect(Collectors.toList());
//定制排序
List<Employee> persons1 = list.stream().sorted((e1, e2) -> {
if (e1.getAge() == e2.getAge()) {
return 0;
} else if (e1.getAge() > e2.getAge()) {
return 1;
} else {
return -1;
}
}).collect(Collectors.toList());
allMatch(Predicate p) | |
anyMatch(Predicate p) | |
noneMatch(Predicate p) | |
findFirst() | |
findAny() | |
count() | |
max(Comparator c) | |
min(Comparator c) | |
forEach(Consumer c) |
@Data
@Builder
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Employee implements Serializable {
private static final long serialVersionUID = -9079722457749166858L;
private String name;
private Integer age;
private Double salary;
private Stauts stauts;
public enum Stauts{
WORKING,
SLEEPING,
VOCATION
}
}
protected List<Employee> employees = Arrays.asList(
new Employee("张三", 18, 9999.99, Employee.Stauts.SLEEPING),
new Employee("李四", 38, 5555.55, Employee.Stauts.WORKING),
new Employee("王五", 60, 6666.66, Employee.Stauts.WORKING),
new Employee("赵六", 8, 7777.77, Employee.Stauts.SLEEPING),
new Employee("田七", 58, 3333.33, Employee.Stauts.VOCATION)
);
1.allMatch()
boolean allMatch(Predicate<? super T> predicate);
boolean match = employees.stream().allMatch((e) -> Employee.Stauts.SLEEPING.equals(e.getStauts()));
System.out.println(match);
boolean anyMatch(Predicate<? super T> predicate);
boolean match = employees.stream().anyMatch((e) -> Employee.Stauts.SLEEPING.equals(e.getStauts()));
System.out.println(match);
boolean noneMatch(Predicate<? super T> predicate);
boolean match = employees.stream().noneMatch((e) -> Employee.Stauts.SLEEPING.equals(e.getStauts()));
System.out.println(match);
Optional<T> findFirst();
Optional<Employee> op = employees.stream().sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())).findFirst();
System.out.println(op.get());
Optional<T> findAny();
Optional<Employee> op = employees.stream().filter((e) -> Employee.Stauts.WORKING.equals(e.getStauts())).findFirst();
System.out.println(op.get());
long count();
long count = employees.stream().count();
System.out.println(count);
Optional<T> max(Comparator<? super T> comparator);
Optional<Employee> op = employees.stream().max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
System.out.println(op.get());
Optional<T> min(Comparator<? super T> comparator);
Optional<Double> op = employees.stream().map(Employee::getSalary).min(Double::compare);
System.out.println(op.get());
void forEach(Consumer<? super T> action);
employees.stream().forEach(System.out::println);
reduce(T iden, BinaryOperator b) | |
reduce(BinaryOperator b) |
T reduce(T identity, BinaryOperator<T> accumulator);
Optional<T> reduce(BinaryOperator<T> accumulator);
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
Integer sum = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(sum);
System.out.println("----------------------------------------");
Optional<Double> op = employees.stream().map(Employee::getSalary).reduce(Double::sum);
System.out.println(op.get());
Optional<Integer> sum = employees.stream()
.map(Employee::getName)
.flatMap(TestStreamAPI1::filterCharacter)
.map((ch) -> {
if(ch.equals('六'))
return 1;
else
return 0;
}).reduce(Integer::sum);
System.out.println(sum.get());
collect(Collector c) |
<R> R collect(Supplier<R> supplier,
BiConsumer<R, ? super T> accumulator,
BiConsumer<R, R> combiner);
<R, A> R collect(Collector<? super T, A, R> collector);
Optional<Double> max = employees.stream()
.map(Employee::getSalary)
.collect(Collectors.maxBy(Double::compare));
System.out.println(max.get());
Optional<Employee> op = employees.stream()
.collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
System.out.println(op.get());
Double sum = employees.stream().collect(Collectors.summingDouble(Employee::getSalary));
System.out.println(sum);
Double avg = employees.stream().collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(avg);
Long count = employees.stream().collect(Collectors.counting());
System.out.println(count);
System.out.println("--------------------------------------------");
DoubleSummaryStatistics dss = employees.stream()
.collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println(dss.getMax());
toList | List<T> | |
toSet | Set<T> | |
toCollection | Collection<T> | |
counting | Long | |
summingInt | Integer | |
averagingInt | Double | |
summarizingInt | IntSummaryStatistics | |
joining | String | |
maxBy | Optional<T> | |
minBy | Optional<T> | |
reducing | ||
collectingAndThen | ||
groupingBy | Map<K, List<T>> | |
partitioningBy | Map<Boolean, List<T>> |
toList | List<Employee> employees= list.stream().collect(Collectors.toList()); |
toSet | Set<Employee> employees= list.stream().collect(Collectors.toSet()); |
toCollection | Collection<Employee> employees=list.stream().collect(Collectors.toCollection(ArrayList::new)); |
counting | long count = list.stream().collect(Collectors.counting()); |
summingInt | int total=list.stream().collect(Collectors.summingInt(Employee::getSalary)); |
averagingInt | double avg= list.stream().collect(Collectors.averagingInt(Employee::getSalary)) |
summarizingInt | IntSummaryStatistics iss= list.stream().collect(Collectors.summarizingInt(Employee::getSalary)); |
Collectors | String str= list.stream().map(Employee::getName).collect(Collectors.joining()); |
maxBy | Optional<Emp>max= list.stream().collect(Collectors.maxBy(comparingInt(Employee::getSalary))); |
minBy | Optional<Emp> min = list.stream().collect(Collectors.minBy(comparingInt(Employee::getSalary))); |
reducing | int total=list.stream().collect(Collectors.reducing(0, Employee::getSalar, Integer::sum)); |
collectingAndThen | int how= list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size)); |
groupingBy | Map<Emp.Status, List<Emp>> map= list.stream() .collect(Collectors.groupingBy(Employee::getStatus)); |
partitioningBy | Map<Boolean,List<Emp>>vd= list.stream().collect(Collectors.partitioningBy(Employee::getManage)); |
public void test4(){
Optional<Double> max = emps.stream()
.map(Employee::getSalary)
.collect(Collectors.maxBy(Double::compare));
System.out.println(max.get());
Optional<Employee> op = emps.stream()
.collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
System.out.println(op.get());
Double sum = emps.stream()
.collect(Collectors.summingDouble(Employee::getSalary));
System.out.println(sum);
Double avg = emps.stream()
.collect(Collecors.averagingDouble(Employee::getSalary));
System.out.println(avg);
Long count = emps.stream()
.collect(Collectors.counting());
DoubleSummaryStatistics dss = emps.stream()
.collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println(dss.getMax());
package io.binghe.concurrency.example.aqs;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;
@Slf4j
public class ForkJoinTaskExample extends RecursiveTask<Integer> {
public static final int threshold = 2;
private int start;
private int end;
public ForkJoinTaskExample(int start, int end) {
this.start = start;
this.end = end;
}
@Override
protected Integer compute() {
int sum = 0;
//如果任务足够小就计算任务
boolean canCompute = (end - start) <= threshold;
if (canCompute) {
for (int i = start; i <= end; i++) {
sum += i;
}
} else {
// 如果任务大于阈值,就分裂成两个子任务计算
int middle = (start + end) / 2;
ForkJoinTaskExample leftTask = new ForkJoinTaskExample(start, middle);
ForkJoinTaskExample rightTask = new ForkJoinTaskExample(middle + 1, end);
// 执行子任务
leftTask.fork();
rightTask.fork();
// 等待任务执行结束合并其结果
int leftResult = leftTask.join();
int rightResult = rightTask.join();
// 合并子任务
sum = leftResult + rightResult;
}
return sum;
}
public static void main(String[] args) {
ForkJoinPool forkjoinPool = new ForkJoinPool();
//生成一个计算任务,计算1+2+3+4
ForkJoinTaskExample task = new ForkJoinTaskExample(1, 100);
//执行一个任务
Future<Integer> result = forkjoinPool.submit(task);
try {
log.info("result:{}", result.get());
} catch (Exception e) {
log.error("exception", e);
}
}
}
LongStream.rangeClosed(0, 10000000L).parallel().reduce(0, Long::sum);
Optional<String> empty = Optional.empty();
String name = "binghe";
Optional<String> opt = Optional.of(name);
assertEquals("Optional[binghe]", opt.toString());
String name = null;
Optional<String> opt = Optional.of(name);
String name = null;
Optional<String> opt = Optional.ofNullable(name);
2.isPresent
Optional<String> opt = Optional.of("binghe");
assertTrue(opt.isPresent());
opt = Optional.ofNullable(null);
assertFalse(opt.isPresent());
if(name != null){
System.out.println(name.length);
}
Optional<String> opt = Optional.of("binghe");
opt.ifPresent(name -> System.out.println(name.length()));
(1)orElse
String nullName = null;
String name = Optional.ofNullable(nullName).orElse("binghe");
assertEquals("binghe", name);
(2)orElseGet
String nullName = null;
String name = Optional.ofNullable(nullName).orElseGet(() -> "binghe");
assertEquals("binghe", name);
public String getDefaultName() {
System.out.println("Getting Default Name");
return "binghe";
}
String text;
System.out.println("Using orElseGet:");
String defaultText = Optional.ofNullable(text).orElseGet(this::getDefaultName);
assertEquals("binghe", defaultText);
System.out.println("Using orElse:");
defaultText = Optional.ofNullable(text).orElse(getDefaultName());
assertEquals("binghe", defaultText);
Using orElseGet:
Getting default name...
Using orElse:
Getting default name...
String name = "binghe001";
System.out.println("Using orElseGet:");
String defaultName = Optional.ofNullable(name).orElseGet(this::getDefaultName);
assertEquals("binghe001", defaultName);
System.out.println("Using orElse:");
defaultName = Optional.ofNullable(name).orElse(getDefaultName());
assertEquals("binghe001", defaultName);
Using orElseGet:
Using orElse:
Getting default name...
4.orElseThrow
String nullName = null;
String name = Optional.ofNullable(nullName).orElseThrow( IllegalArgumentException::new);
5.get
Optional<String> opt = Optional.of("binghe");
String name = opt.get();
assertEquals("binghe", name);
Optional<String> opt = Optional.ofNullable(null);
String name = opt.get();
6.filter
String name = "binghe";
Optional<String> nameOptional = Optional.of(name);
boolean isBinghe = nameOptional.filter(n -> "binghe".equals(name)).isPresent();
assertTrue(isBinghe);
boolean isBinghe001 = nameOptional.filter(n -> "binghe001".equals(name)).isPresent();
assertFalse(isBinghe001);
public class Person{
private int age;
public Person(int age){
this.age = age;
}
//省略get set方法
}
public boolean filterPerson(Peron person){
boolean isInRange = false;
if(person != null && person.getAge() >= 25 && person.getAge() <= 35){
isInRange = true;
}
return isInRange;
}
assertTrue(filterPerson(new Peron(18)));
assertFalse(filterPerson(new Peron(29)));
assertFalse(filterPerson(new Peron(16)));
assertFalse(filterPerson(new Peron(34)));
assertFalse(filterPerson(null));
public boolean filterPersonByOptional(Peron person){
return Optional.ofNullable(person)
.map(Peron::getAge)
.filter(p -> p >= 25)
.filter(p -> p <= 35)
.isPresent();
}
7.map
List<String> names = Arrays.asList("binghe001", "binghe002", "", "binghe003", "", "binghe004");
Optional<List<String>> listOptional = Optional.of(names);
int size = listOptional
.map(List::size)
.orElse(0);
assertEquals(6, size);
String name = "binghe";
Optional<String> nameOptional = Optional.of(name);
int len = nameOptional
.map(String::length())
.orElse(0);
assertEquals(6, len);
String password = " password ";
Optional<String> passOpt = Optional.of(password);
boolean correctPassword = passOpt.filter(
pass -> pass.equals("password")).isPresent();
assertFalse(correctPassword);
correctPassword = passOpt
.map(String::trim)
.filter(pass -> pass.equals("password"))
.isPresent();
assertTrue(correctPassword);
8.flatMap
public class Person {
private String name;
private int age;
private String password;
public Optional<String> getName() {
return Optional.ofNullable(name);
}
public Optional<Integer> getAge() {
return Optional.ofNullable(age);
}
public Optional<String> getPassword() {
return Optional.ofNullable(password);
}
// 忽略get set方法
}
Person person = new Person("binghe", 18);
Optional<Person> personOptional = Optional.of(person);
Optional<Optional<String>> nameOptionalWrapper = personOptional.map(Person::getName);
Optional<String> nameOptional = nameOptionalWrapper.orElseThrow(IllegalArgumentException::new);
String name1 = nameOptional.orElse("");
assertEquals("binghe", name1);
String name = personOptional
.flatMap(Person::getName)
.orElse("");
assertEquals("binghe", name);
public interface MyFunction<T>{
T get(Long id);
default String getName(){
return "binghe";
}
}
public interface MyFunction{
default String getName(){
return "MyFunction";
}
}
public class MyClass{
public String getName(){
return "MyClass";
}
}
public class SubClass extends MyClass implements MyFunction{
}
public class SubClassTest{
@Test
public void testDefaultFunction(){
SubClass subClass = new SubClass();
System.out.println(subClass.getName());
}
}
public interface MyFunction{
default String getName(){
return "function";
}
}
public interface MyInterface{
default String getName(){
return "interface";
}
}
public class MyClass{
@Override
public String getName(){
return MyInterface.super.getName();
}
}
public class MyClass{
@Override
public String getName(){
return MyFunction.super.getName();
}
}
public interface MyFunction{
default String getName(){
return "binghe";
}
static void send(){
System.out.println("Send Message...");
}
}
MyFunction.send();
now() | |
of() | |
plusDays, plusWeeks, plusMonths, plusYears | |
minusDays, minusWeeks, minusMonths, minusYears | |
plus, minus | |
withDayOfMonth, withDayOfYear, withMonth, withYear | |
getDayOfMonth | |
getDayOfYear | |
getDayOfWeek | |
getMonth | |
getMonthValue | |
getYear | |
until | |
isBefore, isAfter | |
isLeapYear |
// 获取当前系统时间
LocalDateTime localDateTime1 = LocalDateTime.now();
System.out.println(localDateTime1);
// 运行结果:2019-10-27T13:49:09.483
// 指定日期时间
LocalDateTime localDateTime2 = LocalDateTime.of(2019, 10, 27, 13, 45,10);
System.out.println(localDateTime2);
// 运行结果:2019-10-27T13:45:10
LocalDateTime localDateTime3 = localDateTime1
// 加三年
.plusYears(3)
// 减三个月
.minusMonths(3);
System.out.println(localDateTime3);
// 运行结果:2022-07-27T13:49:09.483
System.out.println(localDateTime1.getYear()); // 运行结果:2019
System.out.println(localDateTime1.getMonthValue()); // 运行结果:10
System.out.println(localDateTime1.getDayOfMonth()); // 运行结果:27
System.out.println(localDateTime1.getHour()); // 运行结果:13
System.out.println(localDateTime1.getMinute()); // 运行结果:52
System.out.println(localDateTime1.getSecond()); // 运行结果:6
LocalDateTime localDateTime4 = LocalDateTime.now();
System.out.println(localDateTime4); // 2019-10-27T14:19:56.884
LocalDateTime localDateTime5 = localDateTime4.withDayOfMonth(10);
System.out.println(localDateTime5); // 2019-10-10T14:19:56.884
Instant instant1 = Instant.now(); // 默认获取UTC时区
System.out.println(instant1);
// 运行结果:2019-10-27T05:59:58.221Z
// 偏移量运算
OffsetDateTime offsetDateTime = instant1.atOffset(ZoneOffset.ofHours(8));
System.out.println(offsetDateTime);
// 运行结果:2019-10-27T13:59:58.221+08:00
// 获取时间戳
System.out.println(instant1.toEpochMilli());
// 运行结果:1572156145000
// 以Unix元年为起点,进行偏移量运算
Instant instant2 = Instant.ofEpochSecond(60);
System.out.println(instant2);
// 运行结果:1970-01-01T00:01:00Z
Instant instant_1 = Instant.now();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Instant instant_2 = Instant.now();
Duration duration = Duration.between(instant_1, instant_2);
System.out.println(duration.toMillis());
// 运行结果:1000
LocalTime localTime_1 = LocalTime.now();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LocalTime localTime_2 = LocalTime.now();
System.out.println(Duration.between(localTime_1, localTime_2).toMillis());
// 运行结果:1000
LocalDate localDate_1 = LocalDate.of(2018,9, 9);
LocalDate localDate_2 = LocalDate.now();
Period period = Period.between(localDate_1, localDate_2);
System.out.println(period.getYears()); // 运行结果:1
System.out.println(period.getMonths()); // 运行结果:1
System.out.println(period.getDays()); // 运行结果:18
LocalDate nextSunday = LocalDate.now().with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
LocalDateTime localDateTime1 = LocalDateTime.now();
System.out.println(localDateTime1); // 2019-10-27T14:19:56.884
// 获取这个第一天的日期
System.out.println(localDateTime1.with(TemporalAdjusters.firstDayOfMonth())); // 2019-10-01T14:22:58.574
// 获取下个周末的日期
System.out.println(localDateTime1.with(TemporalAdjusters.next(DayOfWeek.SUNDAY))); // 2019-11-03T14:22:58.574
// 自定义:下一个工作日
LocalDateTime localDateTime2 = localDateTime1.with(l -> {
LocalDateTime localDateTime = (LocalDateTime) l;
DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
return localDateTime.plusDays(3);
} else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
return localDateTime.plusDays(2);
} else {
return localDateTime.plusDays(1);
}
});
System.out.println(localDateTime2);
// 运行结果:2019-10-28T14:30:17.400
DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ISO_DATE;
LocalDateTime localDateTime = LocalDateTime.now();
String strDate1 = localDateTime.format(dateTimeFormatter1);
System.out.println(strDate1);
// 运行结果:2019-10-27
// Date -> String
DateTimeFormatter dateTimeFormatter2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String strDate2 = dateTimeFormatter2.format(localDateTime);
System.out.println(strDate2);
// 运行结果:2019-10-27 14:36:11
// String -> Date
LocalDateTime localDateTime1 = localDateTime.parse(strDate2, dateTimeFormatter2);
System.out.println(localDateTime1);
// 运行结果:2019-10-27T14:37:39
// 获取所有的时区
Set<String> set = ZoneId.getAvailableZoneIds();
System.out.println(set);
// [Asia/Aden, America/Cuiaba, Etc/GMT+9, Etc/GMT+8, Africa/Nairobi, America/Marigot, Asia/Aqtau, Pacific/Kwajalein, America/El_Salvador, Asia/Pontianak, Africa/Cairo, Pacific/Pago_Pago, Africa/Mbabane, Asia/Kuching, Pacific/Honolulu, Pacific/Rarotonga, America/Guatemala, Australia/Hobart, Europe/London, America/Belize, America/Panama, Asia/Chungking, America/Managua, America/Indiana/Petersburg, Asia/Yerevan, Europe/Brussels, GMT, Europe/Warsaw, America/Chicago, Asia/Kashgar, Chile/Continental, Pacific/Yap, CET, Etc/GMT-1, Etc/GMT-0, Europe/Jersey, America/Tegucigalpa, Etc/GMT-5, Europe/Istanbul, America/Eirunepe, Etc/GMT-4, America/Miquelon, Etc/GMT-3, Europe/Luxembourg, Etc/GMT-2, Etc/GMT-9, America/Argentina/Catamarca, Etc/GMT-8, Etc/GMT-7, Etc/GMT-6, Europe/Zaporozhye, Canada/Yukon, Canada/Atlantic, Atlantic/St_Helena, Australia/Tasmania, Libya, Europe/Guernsey, America/Grand_Turk, US/Pacific-New, Asia/Samarkand, America/Argentina/Cordoba, Asia/Phnom_Penh, Africa/Kigali, Asia/Almaty, US/Alaska, Asia/Dubai, Europe/Isle_of_Man, America/Araguaina, Cuba, Asia/Novosibirsk, America/Argentina/Salta, Etc/GMT+3, Africa/Tunis, Etc/GMT+2, Etc/GMT+1, Pacific/Fakaofo, Africa/Tripoli, Etc/GMT+0, Israel, Africa/Banjul, Etc/GMT+7, Indian/Comoro, Etc/GMT+6, Etc/GMT+5, Etc/GMT+4, Pacific/Port_Moresby, US/Arizona, Antarctica/Syowa, Indian/Reunion, Pacific/Palau, Europe/Kaliningrad, America/Montevideo, Africa/Windhoek, Asia/Karachi, Africa/Mogadishu, Australia/Perth, Brazil/East, Etc/GMT, Asia/Chita, Pacific/Easter, Antarctica/Davis, Antarctica/McMurdo, Asia/Macao, America/Manaus, Africa/Freetown, Europe/Bucharest, Asia/Tomsk, America/Argentina/Mendoza, Asia/Macau, Europe/Malta, Mexico/BajaSur, Pacific/Tahiti, Africa/Asmera, Europe/Busingen, America/Argentina/Rio_Gallegos, Africa/Malabo, Europe/Skopje, America/Catamarca, America/Godthab, Europe/Sarajevo, Australia/ACT, GB-Eire, Africa/Lagos, America/Cordoba, Europe/Rome, Asia/Dacca, Indian/Mauritius, Pacific/Samoa, America/Regina, America/Fort_Wayne, America/Dawson_Creek, Africa/Algiers, Europe/Mariehamn, America/St_Johns, America/St_Thomas, Europe/Zurich, America/Anguilla, Asia/Dili, America/Denver, Africa/Bamako, Europe/Saratov, GB, Mexico/General, Pacific/Wallis, Europe/Gibraltar, Africa/Conakry, Africa/Lubumbashi, Asia/Istanbul, America/Havana, NZ-CHAT, Asia/Choibalsan, America/Porto_Acre, Asia/Omsk, Europe/Vaduz, US/Michigan, Asia/Dhaka, America/Barbados, Europe/Tiraspol, Atlantic/Cape_Verde, Asia/Yekaterinburg, America/Louisville, Pacific/Johnston, Pacific/Chatham, Europe/Ljubljana, America/Sao_Paulo, Asia/Jayapura, America/Curacao, Asia/Dushanbe, America/Guyana, America/Guayaquil, America/Martinique, Portugal, Europe/Berlin, Europe/Moscow, Europe/Chisinau, America/Puerto_Rico, America/Rankin_Inlet, Pacific/Ponape, Europe/Stockholm, Europe/Budapest, America/Argentina/Jujuy, Australia/Eucla, Asia/Shanghai, Universal, Europe/Zagreb, America/Port_of_Spain, Europe/Helsinki, Asia/Beirut, Asia/Tel_Aviv, Pacific/Bougainville, US/Central, Africa/Sao_Tome, Indian/Chagos, America/Cayenne, Asia/Yakutsk, Pacific/Galapagos, Australia/North, Europe/Paris, Africa/Ndjamena, Pacific/Fiji, America/Rainy_River, Indian/Maldives, Australia/Yancowinna, SystemV/AST4, Asia/Oral, America/Yellowknife, Pacific/Enderbury, America/Juneau, Australia/Victoria, America/Indiana/Vevay, Asia/Tashkent, Asia/Jakarta, Africa/Ceuta, Asia/Barnaul, America/Recife, America/Buenos_Aires, America/Noronha, America/Swift_Current, Australia/Adelaide, America/Metlakatla, Africa/Djibouti, America/Paramaribo, Europe/Simferopol, Europe/Sofia, Africa/Nouakchott, Europe/Prague, America/Indiana/Vincennes, Antarctica/Mawson, America/Kralendijk, Antarctica/Troll, Europe/Samara, Indian/Christmas, America/Antigua, Pacific/Gambier, America/Indianapolis, America/Inuvik, America/Iqaluit, Pacific/Funafuti, UTC, Antarctica/Macquarie, Canada/Pacific, America/Moncton, Africa/Gaborone, Pacific/Chuuk, Asia/Pyongyang, America/St_Vincent, Asia/Gaza, Etc/Universal, PST8PDT, Atlantic/Faeroe, Asia/Qyzylorda, Canada/Newfoundland, America/Kentucky/Louisville, America/Yakutat, Asia/Ho_Chi_Minh, Antarctica/Casey, Europe/Copenhagen, Africa/Asmara, Atlantic/Azores, Europe/Vienna, ROK, Pacific/Pitcairn, America/Mazatlan, Australia/Queensland, Pacific/Nauru, Europe/Tirane, Asia/Kolkata, SystemV/MST7, Australia/Canberra, MET, Australia/Broken_Hill, Europe/Riga, America/Dominica, Africa/Abidjan, America/Mendoza, America/Santarem, Kwajalein, America/Asuncion, Asia/Ulan_Bator, NZ, America/Boise, Australia/Currie, EST5EDT, Pacific/Guam, Pacific/Wake, Atlantic/Bermuda, America/Costa_Rica, America/Dawson, Asia/Chongqing, Eire, Europe/Amsterdam, America/Indiana/Knox, America/North_Dakota/Beulah, Africa/Accra, Atlantic/Faroe, Mexico/BajaNorte, America/Maceio, Etc/UCT, Pacific/Apia, GMT0, America/Atka, Pacific/Niue, Australia/Lord_Howe, Europe/Dublin, Pacific/Truk, MST7MDT, America/Monterrey, America/Nassau, America/Jamaica, Asia/Bishkek, America/Atikokan, Atlantic/Stanley, Australia/NSW, US/Hawaii, SystemV/CST6, Indian/Mahe, Asia/Aqtobe, America/Sitka, Asia/Vladivostok, Africa/Libreville, Africa/Maputo, Zulu, America/Kentucky/Monticello, Africa/El_Aaiun, Africa/Ouagadougou, America/Coral_Harbour, Pacific/Marquesas, Brazil/West, America/Aruba, America/North_Dakota/Center, America/Cayman, Asia/Ulaanbaatar, Asia/Baghdad, Europe/San_Marino, America/Indiana/Tell_City, America/Tijuana, Pacific/Saipan, SystemV/YST9, Africa/Douala, America/Chihuahua, America/Ojinaga, Asia/Hovd, America/Anchorage, Chile/EasterIsland, America/Halifax, Antarctica/Rothera, America/Indiana/Indianapolis, US/Mountain, Asia/Damascus, America/Argentina/San_Luis, America/Santiago, Asia/Baku, America/Argentina/Ushuaia, Atlantic/Reykjavik, Africa/Brazzaville, Africa/Porto-Novo, America/La_Paz, Antarctica/DumontDUrville, Asia/Taipei, Antarctica/South_Pole, Asia/Manila, Asia/Bangkok, Africa/Dar_es_Salaam, Poland, Atlantic/Madeira, Antarctica/Palmer, America/Thunder_Bay, Africa/Addis_Ababa, Asia/Yangon, Europe/Uzhgorod, Brazil/DeNoronha, Asia/Ashkhabad, Etc/Zulu, America/Indiana/Marengo, America/Creston, America/Punta_Arenas, America/Mexico_City, Antarctica/Vostok, Asia/Jerusalem, Europe/Andorra, US/Samoa, PRC, Asia/Vientiane, Pacific/Kiritimati, America/Matamoros, America/Blanc-Sablon, Asia/Riyadh, Iceland, Pacific/Pohnpei, Asia/Ujung_Pandang, Atlantic/South_Georgia, Europe/Lisbon, Asia/Harbin, Europe/Oslo, Asia/Novokuznetsk, CST6CDT, Atlantic/Canary, America/Knox_IN, Asia/Kuwait, SystemV/HST10, Pacific/Efate, Africa/Lome, America/Bogota, America/Menominee, America/Adak, Pacific/Norfolk, Europe/Kirov, America/Resolute, Pacific/Tarawa, Africa/Kampala, Asia/Krasnoyarsk, Greenwich, SystemV/EST5, America/Edmonton, Europe/Podgorica, Australia/South, Canada/Central, Africa/Bujumbura, America/Santo_Domingo, US/Eastern, Europe/Minsk, Pacific/Auckland, Africa/Casablanca, America/Glace_Bay, Canada/Eastern, Asia/Qatar, Europe/Kiev, Singapore, Asia/Magadan, SystemV/PST8, America/Port-au-Prince, Europe/Belfast, America/St_Barthelemy, Asia/Ashgabat, Africa/Luanda, America/Nipigon, Atlantic/Jan_Mayen, Brazil/Acre, Asia/Muscat, Asia/Bahrain, Europe/Vilnius, America/Fortaleza, Etc/GMT0, US/East-Indiana, America/Hermosillo, America/Cancun, Africa/Maseru, Pacific/Kosrae, Africa/Kinshasa, Asia/Kathmandu, Asia/Seoul, Australia/Sydney, America/Lima, Australia/LHI, America/St_Lucia, Europe/Madrid, America/Bahia_Banderas, America/Montserrat, Asia/Brunei, America/Santa_Isabel, Canada/Mountain, America/Cambridge_Bay, Asia/Colombo, Australia/West, Indian/Antananarivo, Australia/Brisbane, Indian/Mayotte, US/Indiana-Starke, Asia/Urumqi, US/Aleutian, Europe/Volgograd, America/Lower_Princes, America/Vancouver, Africa/Blantyre, America/Rio_Branco, America/Danmarkshavn, America/Detroit, America/Thule, Africa/Lusaka, Asia/Hong_Kong, Iran, America/Argentina/La_Rioja, Africa/Dakar, SystemV/CST6CDT, America/Tortola, America/Porto_Velho, Asia/Sakhalin, Etc/GMT+10, America/Scoresbysund, Asia/Kamchatka, Asia/Thimbu, Africa/Harare, Etc/GMT+12, Etc/GMT+11, Navajo, America/Nome, Europe/Tallinn, Turkey, Africa/Khartoum, Africa/Johannesburg, Africa/Bangui, Europe/Belgrade, Jamaica, Africa/Bissau, Asia/Tehran, WET, Europe/Astrakhan, Africa/Juba, America/Campo_Grande, America/Belem, Etc/Greenwich, Asia/Saigon, America/Ensenada, Pacific/Midway, America/Jujuy, Africa/Timbuktu, America/Bahia, America/Goose_Bay, America/Virgin, America/Pangnirtung, Asia/Katmandu, America/Phoenix, Africa/Niamey, America/Whitehorse, Pacif
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。