天天看点

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)
《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

 4 同步视图(线程安全的视图)

典型示例:Collections.synchronizedMap(map);

怎么做到把线程不不安全改成线程安全的呢?在每块可能造成同步问题的线程,都使用同步代码块包裹:

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

小总结:

📌同步操作也可以类似前面的异常操作对类进行扩展

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

 5 被检验视图

典型示例:List<String> list = Collections.checkedList(strings,String.class);

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

全部源自这个 typeCheck()和checkedCopyOf()

typeCheck():直接检查对象是否能转换为指定类型

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

checkedCopyOf():通过复制到泛型类数组,检查是否会抛异常

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

小总结:

📌类型检查操作也可以类似前面的异常、同步操作对类进行扩展

6 可选操作说明

视图不能够完全代替普通集合,只是一些常规操作,以及进行不恰当操作时的异常说明。

视图类可能没有很好的实现接口有些操作上只是写了几个,其他直接抛异常。

对于接口的方法总是覆盖不完全的处理方法:

📌使用类似前面组件一样的适配器,先使用统一的抽象类实现所有方法,其他类在通过继承这个类选用适合自己的方法

📌高版本 JDK 可以考虑直接使用默认方法,写在接口类总

📌对于这部分公共代码书写内容又长又多的情况,建议直接使用模板类

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

 13.3.2 批量处理

典型示例:set.addAll(t);

set中添加集合 t 中的所有元素

典型示例2:set.removeAll(t);

set中删除集合 t 中的所有元素

特别需要注意的是,这些add/remove的操作,是会影响 原数组的,因为它并不是 Collections.retainAll(a,b) 这种格式的,也没有额外返回一个的集合

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

 13.3.3 集合与数组转换

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

 1 数组转集合-基本类型

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public class Main {
    public static void main(String[] args) {
       int[] arr = new int[10];
       for(int i = 0; i < 10; i++){
           arr[i] = i;
       }
 
       //1 直接转
        List<Integer> list = new ArrayList<>();
       for(int item:arr){
           list.add(item);
       }
       System.out.println(list);
       //2 使用 lambda 表达式
        list.clear();
        list = Arrays.stream(arr).boxed().collect(Collectors.toList());;
        System.out.println(list);
    }
}      

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

 2 数组转集合-引用类型

如果需要的集合不可变,直接使用 Arrays.asList(arr) 即可;

如果需要的集合可变,则需要通过 new 关键字创建新的集合

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public class Main {
    public static void main(String[] args) {
       String[] strs = new String[]{"a","b","c"};
       List<String> listStrs = new ArrayList<>(Arrays.asList(strs));
       System.out.println(listStrs);
    }
}      

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

 3 集合转数组-转为 Object 数组

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

public class Main {
    public static void main(String[] args) {
       String[] strs = new String[]{"a","b","c"};
       List<String> listStrs = new ArrayList<>(Arrays.asList(strs));
       Object[] objTransfer = listStrs.toArray();
       System.out.println(Arrays.toString(objTransfer));
    }
}      

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

 4 集合转数组-指定类型

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

import java.util.*;
public class Main {
    public static void main(String[] args) {
       String[] strs = new String[]{"a","b","c"};
       List<String> listStrs = new ArrayList<>(Arrays.asList(strs));
       //指定类型数组,长度不足,按照给定类型创建新数组
       String[] transferStrArr1 = listStrs.toArray(new String[0]);
       System.out.println(Arrays.toString(transferStrArr1));
 
       //指定类型数组,长度足够,拷贝到给定类型数组
       String[] transferStrArr2 = listStrs.toArray(new String[10]);
       System.out.println(Arrays.toString(transferStrArr2));
    }
}      

❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤❤🧡💛💚💙💜🤎🖤

运行结果:

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

🚗🚓🚕🛺🚙🚌🚐🚎🚑🚒🚚🚛🚜🚘🚔🚖🚍🦽🦼🛹🚲🛴🛵🏍

验证一下,看看源码:

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

长度不足内部创建了新对象,再进行拷贝

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

长度足够的情况直接进行拷贝 System.arrayCopy 操作不会创建新的数组,几个参数分别是

《Java 核心技术 卷1》 笔记 第13章 集合(8)视图(二)

对于A复制到B的情况,没有创建新的数组

src对应 A

srcPos 对应从 A 的哪个索引开始复制

dest对应 B

destPos 对应于从 B 的那个索引开始粘贴

Length 就是复制长度

举个小例子,A=[1,2,3,4,5] B=[6,7,8,9,10] src=A,srcPos=1,dest=B,destPos=2,length=3

相当于 A 复制到 B, 从索引1 开始复制3个,也就是复制 [2,3,4]

B 的粘贴位置是 从 2 开始粘贴长度是3个,也就是 [8,9,10] 会被覆盖

最终 B 数组为 [6,7,2,3,4]

小总结:

📌指定类型数组长度不足,创建新数组返回

📌指定类型数组长度足够,按照给定数组返回

总结:

📌同步视图、被检验视图相当于对类的扩展与功能补充

📌集合数组可使用传统方式循环进行拷贝,也可以使用 new ArrayList<>(List.asList()) 和 list.toArray(Type.class) 的方式使用库进行拷贝