第六章一、填空题
1. Java中的I/O流,按照传输数据的不同,可分为**字节流**和**字符流**。
2. File类中**java.io**包中唯一代表磁盘文件本身的对象,它定义了一些与平台无关的方法用于操作文件。
3. 计算机中,无论是文本、图片、音频还是视频,所有文件都是以**二进制**形式存在的。
4. IO提供两个带缓冲的字节流,分别是**BufferedInputStream**和**BufferedOutputStream**。
5. 在JDK中提供了两个类可以将字节流转换为字符流,它们分别是**InputStreamReader**和**OutputStreamWriter**。
二、判断题
1. 错误。如果一个File表示目录下有文件或者子目录,调用delete()方法**不能**将其删除,delete()方法只能删除文件,不能删除非空目录。
2. 正确。File类提供了一系列方法,用于操作其内部封装的路径指向的文件或者目录,boolean exists()方法是判断文件或目录是否存在。
3. 错误。JDK提供了两个抽象类InputStream和OutputStream,它们是字节流的顶级父类,所有的字节输入流都继承自InputStream,所有的字节输出流都继承自OutputStream。
4. 错误。InputStreamReader是Reader的子类,它可以将一个字节输入流转换成字符输入流。
三、选择题
1. 下列选项中,那些是标准输入输出流?(AB)
A、System.In
B、System.Out
2. File类中以字符串形式返回文件绝对路径的方法是哪一项?(C)
C、getAbsolutePath()
3. 下列选项中,那个流使用到了缓冲技术?(A)
A、BufferedOutputStream
4. 在程序开发中,经常需要对文本文件的内容进行读取,如果想从文件中直接读取字符便可以使用字符输入流(C)
C、FileReader
5. File类提供了一系列方法,用于操作其内部封装的路径指向的文件或者目录,当File对象对应的文件不存在时,使用哪个方法将新建的一个File对象指定到新文件中。(C)
C、boolean createNewFile()
四、简答题
1. 字符流与字节流的区别:
- 字节流在操作时,每次读写一个字节,而字符流每次读写一个字符。
- 字节流没有平台依赖性,字符流有平台依赖性,因为字符流涉及到字符集的编码问题。
- 字节流可以处理所有类型的文件,而字符流主要用于处理文本文件。
- 字节流不涉及字符编码问题,字符流需要指定字符编码。
2. InputStreamReader类与OutputStreamWriter类的作用:
- InputStreamReader类是Reader的子类,它的作用是将字节流转换成字符流,即将InputStream中的数据以字符的形式读出来,需要指定字符集。
- OutputStreamWriter类是Writer的子类,它的作用是将字符流转换成字节流,即将Writer中的数据以字节的形式写入到OutputStream中,同样需要指定字符集。
五、编程题
1. 编写一个程序,分别使用字节流和字符流拷贝一个文本文件。要求如下:
```java
import java.io.*;
public class FileCopyExample {
public static void main(String[] args) {
String srcFile = "source.txt"; // 源文件路径
String destFile = "destination.txt"; // 目标文件路径
// 使用字节流拷贝文件
try (FileInputStream fis = new FileInputStream(srcFile);
FileOutputStream fos = new FileOutputStream(destFile)) {
byte[] buffer = new byte[1024];
int length;
while ((length = fis.read(buffer)) != -1) {
fos.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
// 使用字符流拷贝文件
try (FileReader fr = new FileReader(srcFile);
FileWriter fw = new FileWriter(destFile)) {
char[] buffer = new char[1024];
int length;
while ((length = fr.read(buffer)) != -1) {
fw.write(buffer, 0, length);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
``一、填空题
1. **Collection**是所有单列集合的父接口,它定义了单列集合(List和Set)通用的一些方法。
2. 使用Iterator遍历集合时,首先需要调用**hasNext()**方法判断是否存在下一个元素,若存在下一个元素,则调用**next()**方法取出该元素。
3. List集合的主要实现类有**ArrayList**、**LinkedList**,Set集合的主要实现类有**HashSet**、**TreeSet**,Map集合的主要实现类有**HashMap**、**TreeMap**。
4. Map接口是一种双列集合,它的每个元素都包含一个键对象**Key**和值对象**Value**,键和值对象之间存在一种对应关系,称为映射。
5. ArrayList内部封装了一个长度可变的**数组**。
二、判断题
1. 错误。Set集合是通过单一对象来存储的,而不是键值对。
2. 错误。ArrayList集合查询元素的速度很快,但是增删操作效率取决于位置,如果是列表末尾则快,如果是列表中间或开始则较慢。
3. 正确。Set接口主要有两个实现类,分别是HashSet和TreeSet。
4. 正确。Map接口是一种双列集合,它的每个元素都包含一个键对象Key和值对象Value。
5. 错误。Lambda表达式可以是一个表达式或者一个代码块。
三、选择题
1. 以下那些集合可以保存具有映射关系的数据(BC)
B、TreeMap
C、HashMap
2. 下列关于LinkedList类的方法,不是从List接口中继承而来的是(B)
B、pop()
3. 以下属于Map接口集合常用方法的有(AB)
A、boolean containsKey(Object key)
B、Collection values()
4. 使用Iterator时,判断是否存在下一个元素可以使用以下哪个方法(D)
D、hasNext()
5. 阅读下面的代码:
程序的运行结果是(C)
C. Tom,Jerry,Donald
因为字符串数组strs中的元素是字符串对象的引用,for-each循环中修改的是引用指向的对象,而不是数组中的引用本身。
四、简答题
1. 集合List、Set和Map的区别:
- List是一个有序集合,可以包含重复的元素,提供了按索引访问元素的能力。
- Set是一个无序集合,不可以包含重复的元素,不提供按索引访问元素的能力。
- Map是一个键值对集合,每个元素包含一对键和值,键不允许重复,提供了通过键快速访问值的能力。
2. 为什么ArrayList的增删操作比较慢,查找操作比较快:
- ArrayList的增删操作可能涉及到数组的扩容或者元素的移动,这些操作的时间复杂度是O(n),因此相对较慢。
- 查找操作的时间复杂度是O(1),因为可以直接通过索引访问元素,所以比较快。
五、编程题
1. 编写程序:
```java
import java.util.HashSet;
import java.util.Objects;
// Student类
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name) + age;
}
}
// 测试类
public class Test {
public static void main(String[] args) {
HashSet<Student> hs = new HashSet<>();
hs.add(new Student("Alice", 20));
hs.add(new Student("Bob", 22));
hs.add(new Student("Alice", 20)); // 尝试添加一个相等的对象
System.out.println(hs);
}
}
```
2. 编写泛型接口以及其实现类:
```java
import java.util.function.BiConsumer;
// 泛型接口
interface Generic<T> {
void get(T t);
}
// 实现类
class GenericImpl<T> implements Generic<T> {
@Override
public void get(T t) {
// 空实现,可以根据需要添加具体逻辑
}
}
````