WBlog

哀吾生之须臾,羡长江之无穷

0%

《Java核心技术卷Ⅰ(原书12版)》第九章集合

9.5 副本与视图

9.5.1 小集合

Java9引入了一些静态方法生成指定元素的集或列表,还有键值对映射

1
2
3
List<String> names = List.of("Peter", "Paul", "Mary");
Set<Integer> numbers = Set.of(2, 3, 5, 7, 11);
Map<String,Integer> scores = Map.of("Peter", 2, "Paul", 3, "Mary", 5);

ListSet接口有11个方法,分别有0到10个参数,还有一个是有可变参数的方法。

对于Map接口则无法提供参数可变的版本,因为参数类型会交替为键类型和值类型,但是它有一个静态方法ofEntries,能接受任意多个Map.Entry<K,V>对象

1
2
3
4
5
Map<String, String> translations = Map.ofEntries(
Map.entry("book", "Buch"),
Map.entry("pen", "Stift"),
Map.entry("computer", "Computer")
);

这种方式生成的集合对象是不可修改的。如果试图修改它们的内容,会导致UnsupportOperationException异常

若需要可变集合,则可以使用如下方式

1
var names2 = new ArrayList<String>(names);

以下方法调用

1
Collections.nCopies(n,anObject)

会返回一个每个元素都是anObject的不可变的List对象

可以使用以上两种方式建立一个可变的元素已被填充完毕的List

9.5.2 不可修改的副本和视图

可以使用集合类型的copyOf方法建立一个不可修改的副本

1
2
3
4
public static void main(String[] args) {
var names = List.of("Peter", "Paul", "Mary");
var set = Set.copyOf(names);
}

如果原集合恰好不可修改,且类型正确,则copyOf会返回原集合

1
2
3
4
5
6
public static void main(String[] args) {
var names = List.of("Peter", "Paul", "Mary");
var set = Set.copyOf(names);
var set2 = Set.copyOf(names);
System.out.println(set.equals(set2)); // true
}

Collections类还有一些方法可以生成集合不可修改的视图。

当试图修改它的时候会抛出异常

不过当原集合修改,视图会反映这些变化

以下是这些方法的列表:

  1. unmodifiableCollection(Collection<? extends T> c):返回指定集合的不可修改视图。
1
Collection<String> unmodifiableCollection = Collections.unmodifiableCollection(collection);
  1. unmodifiableList(List<? extends T> list):返回指定列表的不可修改视图。
1
List<String> unmodifiableList = Collections.unmodifiableList(list);
  1. unmodifiableSet(Set<? extends T> s):返回指定集合的不可修改视图。
1
Set<String> unmodifiableSet = Collections.unmodifiableSet(set);
  1. unmodifiableSortedSet(SortedSet<T> s):返回指定有序集合的不可修改视图。
1
SortedSet<String> unmodifiableSortedSet = Collections.unmodifiableSortedSet(sortedSet);
  1. unmodifiableNavigableSet(NavigableSet<T> s):返回指定导航集合的不可修改视图。
1
NavigableSet<String> unmodifiableNavigableSet = Collections.unmodifiableNavigableSet(navigableSet);
  1. unmodifiableMap(Map<? extends K, ? extends V> m):返回指定映射的不可修改视图。
1
Map<String, Integer> unmodifiableMap = Collections.unmodifiableMap(map);
  1. unmodifiableSortedMap(SortedMap<K, ? extends V> m):返回指定有序映射的不可修改视图。
1
SortedMap<String, Integer> unmodifiableSortedMap = Collections.unmodifiableSortedMap(sortedMap);
  1. unmodifiableNavigableMap(NavigableMap<K, ? extends V> m):返回指定导航映射的不可修改视图。
1
NavigableMap<String, Integer> unmodifiableNavigableMap = Collections.unmodifiableNavigableMap(navigableMap);

以上就是Java中获取不可修改集合视图的所有方法。

但集合本身属性不会变化,仍然可以被对集合进行增加或删除之类的操作

9.5.3 子范围

可以通过subList方法建立子范围

第一个索引包含在内,而第二个索引不包含

对于子范围的所有操作都会反映到整个列表

下列操作就是删除子视图后,原列表的对应元素也被删去了

1
2
3
4
5
6
7
8
public static void main(String[] args) {
var staff = new ArrayList<Integer>(List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
var view = staff.subList(0, 3);
System.out.println(view); // [1, 2, 3]
view.clear();
System.out.println(view); // []
System.out.println(staff); // [4, 5, 6, 7, 8, 9, 10]
}

对于有序集和映射,可以使用范围而非索引建立子范围

SortedSet接口声明了3个方法

1
2
3
Sorted<E> subSet(E from,to)
Sorted<E> headSet(E to)
Sorted<E> tailSet(E from)

有序映射也有类似的方法

9.5.4 检查型视图