Tips

做一个终身学习的人。

在本章中,主要介绍以下内容:

  • 在JDK 9之前如何创建了不可变的list,set和map以及使用它们的问题。
  • 如何使用JDK 9中的List接口的of()静态工厂方法创建不可变的list。

    如何使用JDK 9中的Set接口的of()静态工厂方法创建不可变的set。

    如何使用JDK 9中的Map接口的of()ofEntries()entry()静态工厂方法创建不可变的map。

一. 背景

Collection API由类和接口组成,提供了一种保存和操作不同类型的对象集合的方法,例如list,set和map。 它在Java SE 1.2版本中添加进来。 Java编程语言不支持Collection Literals,这是一种简单易用的方式来声明和初始化集合。 Collection Literals允许通过在紧凑形式的表达式中指定集合的元素来创建特定类型的集合。 Collection Literals的一个示例是一个列表文字,能够创建一个列表,其中包含100和200的整数,如下所示:

List<Integer> list = [100, 200];

Collection Literals紧凑,使用简单。 由于在创建时已知元素的数量,因此可以实现高效的内存使用。 它可以设计成不可变的,使其线程安全。

在Java编程语言中包含Collection Literals语法在JDK 9之前被考虑过几次。 Java设计师决定不将Collection Literals添加到Java语言中,至少不在JDK 9中。在这一点上将Collection Literals添加到Java将需要太多的努力来获得太少的收益。 他们决定通过在ListSetMap接口中添加静态工厂方法来更新Collection API,从而可以轻松有效地创建小型的,不可变的集合来实现相同的目标。

现有的Collection API创建可变集合。 可以通过将可变集合包装在另一个对象中创建一个不可变的(或不可修改的)集合,该对象只是原始可变对象的包装器。 要在JDK 8或更早版本中创建两个整数的无法修改的列表,通常使用以下代码片段:

// Create an empty, mutable list
List<Integer> list = new ArrayList<>();
// Add two elements to the mutable list
list.add(100);
list.add(200);
// Create an immutable list by wrapping the mutable list
List<Integer> list2 = Collections.unmodifiableList(list);

这种做法有严重的缺陷。 不可变的list只是可修改list的包装。 有意的是,将变量名为list。 不能使用list2变量修改列表。但是,仍然可以使用list 变量来修改列表,并且在使用list2变量读取list时将会反映出修改。 下面包含一个完整的程序来创建一个不可变的list,并显示如何在以后更改其内容。

// PreJDK9UnmodifiableList.java
package com.jdojo.collection;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class PreJDK9UnmodifiableList {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(100);
list.add(200);
System.out.println("list = " + list);
// Create an unmodifiable list
List<Integer> list2 = Collections.unmodifiableList(list);
System.out.println("list2 = " + list2);
// Let us add an element using list
list.add(300);
// Print the contents of the list using both
// variables named list and list2
System.out.println("list = " + list);
System.out.println("list2 = " + list2);
}
}

输出结果为:

list = [100, 200]
list2 = [100, 200]
list = [100, 200, 300]
list2 = [100, 200, 300]

输出显示,只要保留原始列表的引用,就可以更改其内容,并且不可变的list也不是真正不可变的! 解决此问题的方法是使用新的不可变list引用来覆盖原始引用变量,如下所示:

List<Integer> list = new ArrayList<>();
list.add(100);
list.add(200);
// Create an unmodifiable list and store it in list
list = Collections.unmodifiableList(list);

注意,此示例使用多个语句来创建和填入不可变的list。 如果需要在类中声明和初始化不可变的list作为实例或静态变量,则该方法不起作用,因为它涉及多个语句。 这样一个声明需要简单,紧凑,并且包含在一个声明中。 如果在类中使用以前的代码来实例变量,那么代码将类似于以下代码:

public class Test {
private List<Integer> list = new ArrayList<>();
{
list.add(100);
list.add(200);
list = Collections.unmodifiableList(list);
}
// ...
}

还有其他方式来声明和初始化一个不可变的list,例如使用数组并将其转换为list。 其中三种方式如下:

public class Test {
// Using an array and converting it to a list
private List<Integer> list2 = Collections.unmodifiableList( new ArrayList<>( Arrays.asList(100, 200)));
// Using an anonymous class
private List<Integer> list3 = Collections.unmodifiableList( new ArrayList<>(){{add(100); add(200);}});
// Using a stream
private List<Integer> list4 = Collections.unmodifiableList( Stream.of(100, 200).collect(Collectors.toList()));
// More code goes here
}

此示例证明可以在一个语句中具有不可变的list。 但是,语法是冗长的。 再是效率低下。 例如,只要在list中保存两个整数,则需要创建具有后备数组对象的多个对象来保存这些值。

JDK 9通过向ListSetMap接口提供静态工厂方法来解决这些问题。 该方法命名为of()并且被重载。 在JDK 9中,可以声明和初始化两个元素的不可变列表,如下所示:

// Create an unmodifiable list of two integers
List<Integer> list = List.of(100, 200);

二. 不可变的list

JDK 9将of()静态工厂方法重载到List接口。 它提供了一种简单而紧凑的方式来创建不可变的list。 以下是of()方法的所有版本:

static <E> List<E> of()
static <E> List<E> of(E e1)
static <E> List<E> of(E e1, E e2)
static <E> List<E> of(E e1, E e2, E e3)
static <E> List<E> of(E e1, E e2, E e3, E e4)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
static <E> List<E> of(E... elements)

of()方法有11个特定版本来创建零到十个元素的list。 另一个版本采用可变参数来允许创建任何数量的元素的不可变的list。 你可能会想知道当使用可变参数的版本可以创建具有任意数量的元素的列表时,为什么有这么多版本的方法。 它们存在为性能原因。 API设计人员希望能够有效地使用少量元素的列表。 使用数组实现可变参数。 存在具有非可变参数的方法,以避免将参数装入数组中,这使得它们更有效率。 这些方法使用List接口的特殊实现类用于较小的list。

of()方法返回的list具有以下特征:

  • 结构上是不可变的。 尝试添加,替换或删除元素会抛出UnsupportedOperationException异常。
  • 不允许null元素。 如果列表中的元素为null,则抛出NullPointerException异常。
  • 如果所有元素是可序列化的,那么它们也是可序列化的。
  • 元素的顺序与of()方法中指定的,与of(E… elements) 方法的可变参数版本中使用的数组相同。
  • 对返回的列表的实现类没有保证。 也就是说,不要指望返回的对象是ArrayList或任何其他实现List接口的类。 这些方法的实现是内部的,不应该假定他们的类名。 例如,List.of()List.of("A")可能会返回两个不同类的对象。

Collections类包含一个EMPTY_LIST的静态属性,表示不可变的空list。 它还包含一个emptyList()的静态方法来获取不可变的空list。singletonList(T object)方法返回具有指定元素的不可变单例list。 以下代码片段显示了JDK 9和JDK 9之前创建不可变的空和单例list的方式。

// Creating an empty, immutable List before JDK 9
List<Integer> emptyList1 = Collections.EMPTY_LIST;
List<Integer> emptyList2 = Collections.emptyList();
// Creating an empty list in JDK 9
List<Integer> emptyList = List.of();
// Creating a singleton, immutable List before JDK 9
List<Integer> singletonList1 = Collections.singletonList(100);
// Creating a singleton, immutable List in JDK 9
List<Integer> singletonList = List.of(100);

如何使用of()方法从数组中创建一个不可变的list? 答案取决于你想要从数组的列表。 可能需要一个list,其元素与数组的元素相同,或者可能希望使用数组本身作为列表中唯一元素的list。 使用List.of(array)将调用of(E... elements)方法,返回的列表将其元素与数组中的元素相同。 如您希望数组本身是list中的唯一元素,则需要使用List.<array-type>of(array) 方法,这将调用of(E e1)方法,返回的列表将具有一个 元素,它是数组本身。 以下代码使用Integer数组来演示:

Integer[] nums = {100, 200};
// Create a list whose elements are the same as the elements
// in the array
List<Integer> list1 = List.of(nums);
System.out.println("list1 = " + list1);
System.out.println("list1.size() = " + list1.size());
// Create a list whose sole element is the array itself
List<Integer[]> list2 = List.<Integer[]>of(nums);
System.out.println("list2 = " + list2);
System.out.println("list2.size() = " + list2.size());

输出结果为:

list1 = [100, 200]
list1.size() = 2
list2 = [[Ljava.lang.Integer;@27efef64]
list2.size() = 1

下面包含一个完整的程序,显示如何使用List接口的of()静态工厂方法来创建不可变的list。

// ListTest.java
package com.jdojo.collection;
import java.util.List;
public class ListTest {
public static void main(String[] args) {
// Create few unmodifiable lists
List<Integer> emptyList = List.of();
List<Integer> luckyNumber = List.of(19);
List<String> vowels = List.of("A", "E", "I", "O", "U");
System.out.println("emptyList = " + emptyList);
System.out.println("singletonList = " + luckyNumber);
System.out.println("vowels = " + vowels);
try {
// Try using a null element
List<Integer> list = List.of(1, 2, null, 3);
} catch(NullPointerException e) {
System.out.println("Nulls not allowed in List.of().");
}
try {
// Try adding an element
luckyNumber.add(8);
} catch(UnsupportedOperationException e) {
System.out.println("Cannot add an element.");
}
try {
// Try removing an element
luckyNumber.remove(0);
} catch(UnsupportedOperationException e) {
System.out.println("Cannot remove an element.");
}
}
}

输出结果为:

emptyList = []
singletonList = [19]
vowels = [A, E, I, O, U]
Nulls not allowed in List.of().
Cannot add an element.
Cannot remove an element .

三. 不可变的set

JDK 9在Set接口中添加了of()静态工厂方法的重载。 它提供了一种简单而紧凑的方式来创建不可变的set。 以下是of()方法的所有版本:

static <E> Set<E> of()
static <E> Set<E> of(E e1)
static <E> Set<E> of(E e1, E e2)
static <E> Set<E> of(E e1, E e2, E e3)
static <E> Set<E> of(E e1, E e2, E e3, E e4)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
static <E> Set<E> of(E... elements)

of()方法的所有版本为性能都做了调整。 可以使用前11个版本来创建一个不可变的零到十个元素的set。 of方法的前11个版本与可变参数的版本一起存在的原因是为了避免将参数装入数组中,最多可设置10个元素。 可变参数的版本可用于创建一个包含任意数量元素的不可变set。

of()方法返回的set具有以下特征:

  • 结构上是不可变的。 尝试添加,替换或删除元素会抛出UnsupportedOperationException异常。
  • 不允许null元素。 如果set中的元素为null,则抛出NullPointerException异常。
  • 如果所有元素是可序列化的,那么它们是可序列化的。
  • 不允许重复元素。 指定重复的元素会引发一个IllegalArgumentException
  • 元素的迭代顺序是未指定的。
  • 对于返回的集合的实现类不能保证。 也就是说,不要指望返回的对象是HashSet或任何其他实现Set接口的类。 这些方法的实现是内部的,不应该假定他们的类名。 例如,Set.of()Set.of(“A”)可能返回两个不同类的对象。

Collections类包含一个EMPTY_SET的静态属性,表示不可变的空set。 它还包含emptySet()的静态方法来获取不可变的空set。 它的singleton(T object)方法返回具有指定元素的不可变单例set。 以下代码片段显示了JDK 9和JDK 9之前创建不可变的空和单例set的方法:

// Creating an empty, immutable Set before JDK 9
Set<Integer> emptySet1 = Collections.EMPTY_SET;
Set<Integer> emptySet2 = Collections.emptySet();
// Creating an empty Set in JDK 9
Set<Integer> emptySet = Set.of();
// Creating a singleton, immutable Set before JDK 9
Set<Integer> singletonSet1 = Collections.singleton(100);
// Creating a singleton, immutable Set in JDK 9
Set<Integer> singletonSet = Set.of(100);

以下代码显示了如何从数组中创建一个不可变的set。 可以有一个set的元素与数组的元素相同,或者可以使用集合作为唯一元素的集合。 注意,当使用数组元素作为集合的元素时,该数组不能具有重复的元素。 否则,Set.of()方法将抛出IllegalArgumentException异常。

Integer[] nums = {100, 200};
// Create a set whose elements are the same as the
// elements of the array
Set<Integer> set1 = Set.of(nums);
System.out.println("set1 = " + set1);
System.out.println("set1.size() = " + set1.size());
// Create a set whose sole element is the array itself
Set<Integer[]> set2 = Set.<Integer[]>of(nums);
System.out.println("set2 = " + set2);
System.out.println("set2.size() = " + set2.size());
// Create an array with duplicate elements
Integer[] nums2 = {101, 201, 101};
// Try creating a set with the array as its sole element
Set<Integer[]> set3 = Set.<Integer[]>of(nums2);
System.out.println("set3 = " + set3);
System.out.println("set3.size() = " + set3.size());
try {
// Try creating a set whose elements are the elements of
// the array. It will throw an IllegalArgumentException.
Set<Integer> set4 = Set.of(nums2);
System.out.println("set4 = " + set4);
} catch(IllegalArgumentException e) {
System.out.println(e.getMessage());
}

输出结果为:

set1 = [100, 200]
set1.size() = 2
set2 = [[Ljava.lang.Integer;@47c62251]
set2.size() = 1
set3 = [[Ljava.lang.Integer;@3e6fa38a]
set3.size() = 1
duplicate element: 101

下面包含一个完整的程序,显示如何使用Set接口的of()静态工厂方法来创建不可变的set。 注意程序中包含元音元素的set的输出。 组合的元素可能不会以创建set时指定的相同顺序输出,因为set不保证其元素的顺序。

// SetTest.java
package com.jdojo.collection;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
// Create few unmodifiable sets
Set<Integer> emptySet = Set.of();
Set<Integer> luckyNumber = Set.of(19);
Set<String> vowels = Set.of("A", "E", "I", "O", "U");
System.out.println("emptySet = " + emptySet);
System.out.println("singletonSet = " + luckyNumber);
System.out.println("vowels = " + vowels);
try {
// Try using a null element
Set<Integer> set = Set.of(1, 2, null, 3);
} catch(NullPointerException e) {
System.out.println("Nulls not allowed in Set.of().");
}
try {
// Try using duplicate elements
Set<Integer> set = Set.of(1, 2, 3, 2);
} catch(IllegalArgumentException e) {
System.out.println(e.getMessage());
}
try {
// Try adding an element
luckyNumber.add(8);
} catch(UnsupportedOperationException e) {
System.out.println("Cannot add an element.");
}
try {
// Try removing an element
luckyNumber.remove(0);
} catch(UnsupportedOperationException e) {
System.out.println("Cannot remove an element.");
}
}
}

以下是输出结果:

emptySet = []
singletonSet = [19]
vowels = [E, O, A, U, I]
Nulls not allowed in Set.of().
duplicate element: 2
Cannot add an element.
Cannot remove an element.

四. 不可变的map

JDK 9将of()静态工厂方法重载添到Map接口中。 它提供了一种简单而紧凑的方式来创建不可变的map。 方法的实现为性能做了调整。 以下是of()方法的11个版本,可以创建一个不可变的零到十个键值条目的map:

static <K,V> Map<K,V> of()
static <K,V> Map<K,V> of(K k1, V v1)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9)
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5, K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10)

注意在of()方法中的参数的位置。 第一个和第二个参数分别是map中第一个键值对的键和值;第三个和第四个参数分别是map中第二个键值对的键和值。 注意,在Map中,没有像在ListSet中可变参数的of()方法。 这是因为Map条目包含两个值(键值和值),并且Java中的方法中只能有一个可变参数。 以下代码片段显示了如何使用of()方法创建map:

// An empty, unmodifiable Map
Map<Integer, String> emptyMap = Map.of();
// A singleton, unmodifiable Map
Map<Integer, String> singletonMap = Map.of(1, "One");
// A unmodifiable Map with two entries
Map<Integer, String> luckyNumbers = Map.of(1, "One", 2, "Two");

要创建具有任意数量条目的不可修改的Map,JDK 9在Map接口中提供了一个ofEntries()的静态方法,它的签名如下:

<K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)

要使用ofEntries()方法,需要在Map.Entry实例中包含每个map键值对。 JDK 9在Map接口中提供了一个方便的entry()静态方法来创建Map.Entry的实例。 entry()方法的签名如下:

<K,V> Map.Entry<K,V> entry(K k, V v)

为了保持表达式的可读性和紧凑性,需要为Map.entry方法使用静态导入,并使用如下所示的语句来创建一个具有任意数量条目的不可修改的map:

import java.util.Map;
import static java.util.Map.entry;
// ...
// Use the Map.ofEntries() and Map.entry() methods to
// create an unmodifiable Map
Map<Integer, String> numberToWord =
Map.ofEntries(entry(1, "One"),
entry(2, "Two"),
entry(3, "Three"));

Map接口的of()ofEntries()方法返回的map具有以下特征:

  • 在结构上是不可变的。 尝试添加,替换或删除条目会抛出UnsupportedOperationException异常。
  • 不允许在键或值中为null。 如果map中的键或值为null,则抛出NullPointerException异常。
  • 如果所有键和值都是可序列化的,它们是可序列化的。
  • 不允许重复的键。 指定重复的键会引发IllegalArgumentException异常。
  • 映射的迭代顺序是未指定的。
  • 对于返回的Map的实现类不能保证。 也就是说,不要指望返回的对象是HashMap或实现Map接口的任何其他类。 这些方法的实现是内部的,不应该假定他们的类名。 例如,Map.of()Map.of(1, "One")可能会返回两个不同类的对象。

Collections类包含EMPTY_MAP的静态字段,表示不可变的空map。 它还包含一个emptyMap()的静态方法来获取不可变的空map。 singletonMap(K key, V value)方法返回具有指定键和值的不可变的单例map。 以下代段显示了JDK 9和JDK 9之前创建不可变空map和单例map的方式:

// Creating an empty, immutable Map before JDK 9
Map<Integer,String> emptyMap1 = Collections.EMPTY_MAP;
Map<Integer,String> emptyMap2 = Collections.emptyMap();
// Creating an empty Map in JDK 9
Map<Integer,String> emptyMap = Map.of();
// Creating a singleton, immutable Map before JDK 9
Map<Integer,String> singletonMap1 =
Collections.singletonMap(1, "One");
// Creating a singleton, immutable Map in JDK 9
Map<Integer,String> singletonMap = Map.of(1, "One");

下面包含一个完整的程序,显示如何使用Map接口的of()ofEntries()entry() 静态方法来创建不可变的

map。 请注意map中指定日期的顺序以及输出中显示的顺序。 它们可能不匹配,因为map更像set,不能保证其条目的检索顺序。

// MapTest.java
package com.jdojo.collection;
import java.util.Map;
import static java.util.Map.entry;
public class MapTest {
public static void main(String[] args) {
// Create few unmodifiable maps
Map<Integer,String> emptyMap = Map.of();
Map<Integer,String> luckyNumber = Map.of(19, "Nineteen");
Map<Integer,String> numberToWord =
Map.of(1, "One", 2, "Two", 3, "Three");
Map<String,String> days = Map.ofEntries(
entry("Mon", "Monday"),
entry("Tue", "Tuesday"),
entry("Wed", "Wednesday"),
entry("Thu", "Thursday"),
entry("Fri", "Friday"),
entry("Sat", "Saturday"),
entry("Sun", "Sunday"));
System.out.println("emptyMap = " + emptyMap);
System.out.println("singletonMap = " + luckyNumber);
System.out.println("numberToWord = " + numberToWord);
System.out.println("days = " + days);
try {
// Try using a null value
Map<Integer,String> map = Map.of(1, null);
} catch(NullPointerException e) {
System.out.println("Nulls not allowed in Map.of().");
}
try {
// Try using duplicate keys
Map<Integer,String> map = Map.of(1, "One", 1, "On");
} catch(IllegalArgumentException e) {
System.out.println(e.getMessage());
}
try {
// Try adding an entry
luckyNumber.put(8, "Eight");
} catch(UnsupportedOperationException e) {
System.out.println("Cannot add an entry.");
}
try {
// Try removing an entry
luckyNumber.remove(0);
} catch(UnsupportedOperationException e) {
System.out.println("Cannot remove an entry.");
}
}
}

输出结果为:

emptyMap = {}
singletonMap = {19=Nineteen}
numberToWord = {1=One, 3=Three, 2=Two}
days = {Sat=Saturday, Tue=Tuesday, Thu=Thursday, Sun=Sunday, Wed=Wednesday, Fri=Friday, Mon=Monday}
Nulls not allowed in Map.of().
duplicate key: 1
Cannot add an entry.
Cannot remove an entry.

五. 总结

在Java语言中支持collection literals是非常需要的功能。 JDK 9替代了对collection literals的支持,更新了Collection API,而是在ListSetMap接口中添加了of()静态工厂方法,分别返回一个不可变的ListSetMap。该方法被重载,指定集合的​​零到十个元素。 ListSet接口提供了可变参数的of()方法,用于创建一个包含任意数量的元素的ListSetMap接口提供了ofEntries() 静态工厂方法,用于创建一个不可变的任意数量条目的MapMap接口还包含一个静态的entry()方法,它接受一个键和一个值作为参数并返回一个Map.Entry实例。 ofEntries()entry()方法一起使用来创建任意数量条目的不可变的Map

这些接口中的新的静态工厂方法为性能做了调整。 List.of()Set.of()方法不允许使用null元素。 Set.of()方法不允许重复的元素。 Map.of()Map.ofEntries()方法不允许重复键,或者将null作为键或值。

Java 9 揭秘(13. Collection API 更新)的更多相关文章

  1. Java 9 揭秘全目录汇总

    Tips 做一个终身学习的人. 当写这篇文章时,关于Java 9的学习就先告一段落了. 首先介绍一下背景,大概两个月前,我突然有兴趣想看看Java 9,当时读了一本英文原著<Java 9 Rev ...

  2. 《Java 9 揭秘》全目录汇总

    Tips 做一个终身学习的人. 当写这篇文章时,关于Java 9的学习就先告一段落了. 首先介绍一下背景,大概两个月前,我突然有兴趣想看看Java 9,当时读了一本英文原著<Java 9 Rev ...

  3. Java 9 揭秘(12. Process API 更新)

    Tips 做一个终身学习的人. 在本章中,主要介绍以下内容: Process API是什么 如何创建本地进程 如何获取新进程的信息 如何获取当前进程的信息 如何获取所有系统进程的信息 如何设置创建,查 ...

  4. Java 9 揭秘(10. 模块API)

    Tips 做一个终身学习的人. 在本章节中,主要介绍以下内容: 什么是模块 API 如何在程序中表示模块和模块描述 如何读取程序中的模块描述 如何表示模块的版本 如何使用Module和ModuleDe ...

  5. Java 9 揭秘(20. JDK 9中API层次的改变)

    Tips 做一个终身学习的人. 在最后一章内容中,主要介绍以下内容: 下划线作为新关键字 改进使用try-with-resources块的语法 如何在匿名类中使用<>操作符 如何在接口中使 ...

  6. Java设置的读书笔记和集合框架Collection API

    一个.CollectionAPI 集合是一系列对象的聚集(Collection). 集合在程序设计中是一种重要的数据接口.Java中提供了有关集合的类库称为CollectionAPI. 集合实际上是用 ...

  7. Java 集合系列 13 WeakHashMap

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  8. Java 集合系列 02 Collection架构

    java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...

  9. Java 8时间和日期API 20例

    本文由 ImportNew - Sandy 翻译自 javarevisited.欢迎加入翻译小组.转载请见文末要求. 伴随lambda表达式.streams以及一系列小优化,Java 8 推出了全新的 ...

随机推荐

  1. 从零开始的JS生活(三)——内置对象

    咱们继续进行我们的正经的JS介绍.今天所要跟大家讲述的是JS中十分常用.十分常用.十分常用的内置对象. 一.世界上最熟悉的陌生就是,当你看着数组.而我看着你... - 数组对象 1.数组的概念 在内存 ...

  2. numpy中linspace用法 (等差数列创建函数)

    linspace  函数 是创建等差数列的函数, 最好是在 Matlab  语言中见到这个函数的,近期在学习Python 中的 Numpy, 发现也有这个函数,以下给出自己在学习过程中的一些总结. ( ...

  3. 包装FTPWebRequest类

    上篇文章讨论了C#从基于FTPS的FTP server下载数据 (FtpWebRequest 的使用)SSL 加密.不过细心的朋友应该可以发现FTPWebRequest 每次都是新生成一个reques ...

  4. iOS开发之资讯类App常用分类控件的封装与实现(CollectionView+Swift3.0+)

    今天博客中,我们就来实现一下一些常用资讯类App中常用的分类选择的控件的封装.本篇博客中没有使用到什么新的技术点,如果非得说用到了什么新的技术点的话,那么勉强的说,用到了一些iOS9以后UIColle ...

  5. Shiro眼皮下玩ajax,玩出302 Found(实践得经验)

    2017/06/14这一天,是我玩Shiro安全框架最刻骨铭心的一天.因为Shiro今天给我深深的补了一刀,在这儿我也给各位补一刀吧,其实问题很简单,解决方式也极其简单,只是给各位分享一下这个错误,纯 ...

  6. flask 扩展之 -- flask-login

    一. 使用 Werkzeug 实现密码散列. generate_password_hash(password, method=pbkdf2:sha1, salt_length=8) 将原始密码作为输入 ...

  7. 浅谈Swift和OC的区别

    前言 转眼Swift3都出来快一年了,从OC到Swift也经历了很多,所以对两者的一些使用区别也总结了一点,暂且记录下,权当自己的一个笔记. 当然其中一些区别可能大家都有耳闻,所以这里也会结合自身的一 ...

  8. Kafka官方文档翻译——简介

    简介 Kafka擅长于做什么? 它被用于两大类应用: 在应用间构建实时的数据流通道 构建传输或处理数据流的实时流式应用 几个概念: Kafka以集群模式运行在1或多台服务器上 Kafka以topics ...

  9. Kubernetes服务之StatefulSets简介

    StatefulSets在v1.5时还是个beta特性,它取代了v1.4的PetSets特性.PetSets的用户可以参考v1.5的升级指导,将正在运行的PeetSets升级到StatefulSets ...

  10. ICG_System之全自动代码生成器V2.0版本

    大家好! 早在2014年本人就已经利用业余时间开发自己的ICG之代码生成器系统.依靠bootstrap的崛起本人也在不断完善此应用.目的是为了减少开发人员的工作量. 减少不必要的复制粘贴操作,该系统已 ...