收集
收集(或容器)是代表一个对象组的单个对象,其它对象被认为是它的元素。收集用于处理多种类型对象的问题,所有的类型都有一个特殊的种类(也就是说,它们都是从一个共同父类继承来的)。Java编程语言支持收集类Vector,Bits, Stack,Hashtable ,LinkedList等等。例如,Stack实现后进先出(LIFO)的顺序,Hashtable提供一个相关的对象数组。
收集可用于保存,处理Object类型的对象。这允许在收集中贮存任何对象。它还可以,在使用对象前、从收集中检索到它之后,使用正确的类型转换为我们所需要的对象类型。
收集API典型地由将对象保持为下述情况的接口而组成:
(Collection)收集-没有具体顺序的一组对象
(Set)设定-没有复制的一组对象
(List)列表-有序对象组,允许复制
API还包括诸如HashSet, ArraySet, ArrayList, LinkedList和Vector等等的类,它们实现这些接口。API还提供了支持某些算法的方法,如:排序,二进制搜索,计算列表中的最小和最大等。
Collections API的体系结构
集合是代表一组对象的单个对象。集合中的对象叫元素。
我们在程序设计中经常会用到各种各样的数据结构,如:表、映射、清单、树、集合等。显然,这些数据结构都满足集合的定义。为了方便我们处理各种各样的数据结构,Java在Java.util包中提供了一组API。这组API中的大部分类都实现了Collection接口,因此,被称作Collections API。根据它们处理的不同种类的数据结构,Collections API可分为三类:
Collection:一组没有顺序的对象,允许重复相同的元素。
Set:一组没有顺序的对象,不允许重复相同的元素。
List:一组有顺序的对象,允许重复相同的元素。
Collections API包括诸如HashSet, ArraySet, ArrayList, LinkedList和Vector等等的类。Collections API支持常用算法:排序,二进制搜索,求最小值和最大值等等。
Collection接口和类的体系结构有助于我们理解Collections API
例分析
命令行参数
例1
问题的描述:
通过命令行参数给程序输入数据
解决方案:
当一个Java应用程序从终端启动时,用户可以提供零个或多个命令行参数。这些命令行参数都是字符串,这些字符串可以是独立的记号(如:arg1),也可以是引号之间的多个符号("another arg")。参数序列跟在程序类的名字后面输入;然后被存放在String 对象的数组中,传递给main 方法。
请看下例:
class TestArgs {
public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
编译,运行以及输出的结果为:
例2
系统属性
问题的描述:
通过系统属性给程序传入数据
解决方案:
系统属性是另外一种在运行时向程序传递参数的机制。每个属性都是一个属性名和属性值的映射对。属性名和属性值都是字符串。Properties 类表示这样的映射。System.getProperties方法返回系统的属性对象。System.getProperties(String)方法返回String属性的值。System.getProperties(String, String)方法允许你在属性名不存在时返回默认值。你可以使用递归调用PropertyNames方法遍历全部属性名的集合;对每个属性名调用getProperty方法得到所有属性的值。
请看下例:
import java.util.*;
class TestSP // System Properties
{
public static void main(String[] args) {
Properties p = System.getProperties(); // 第六行
Enumeration e = p.propertyNames(); // 第七行
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
if (name.equals("aaa")) {
String value = p.getProperty(name);
System.out.println("name: " + name + " value: " + value);
}
}
}
}
分析:第六行取得系统属性的集合,第七行从属性集合中得到属性名的枚举。枚举对象允许程序循环遍历其中的所有元素。这一点与迭代相似。hasMoreElements 方法判断枚举中是否还有后续元素,nextElement方法返回枚举中的下一个元素。
运行:
java -Daaa=345 TestSP //-D后面是属性的名字,=后面是属性的值 ,注意是大写的D
输出结果摘录如下:
例3
标准的输入
问题的描述:
标准的输入
解决方案:
多数应用都会发生人机交互。人机交互经常通过控制台文本输入/输出来完成。
Java 2 SDK 用公有类java.lang.System支持控制台I/O。
System.out是一个PrintStream对象,它指向运行Java应用程序的终端窗口。
System.in是一个InputStream对象,它指向用户的键盘。
请看下例:
import java.io.*;
class TestKI // Keyboard Input
{
public static void main(String[] args) {
String s;
// 进行字符串的包装,就可以读取一行字符串
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
System.out.println("按 ctrl+c 键 或者输入exit 退出程序!");
try {
s = br.readLine();
// 如果按 ctrl+c 键,那么s==null,所以要先进行s!=null判断,不然
// 会出现空指针异常(调用s.equals("exit"))
while (s != null && !s.equals("exit")) {
System.out.println("Read: " + s);
s = br.readLine();
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
编译和运行的结果为:
例4
程序中实现文件的创建,读,写
问题的描述:
在程序中实现文件的创建,读,写
解决方案:
Input/Output(I/O)是程序中最重要的元素之一。Java技术包含了一套丰富的I/O流。这一节我们要讲解文件中字符数据的读写。我们将讲述:
创建文件对象。
操作文件对象。
读写文件流。
创建一个新的File对象
File类提供了若干处理文件和获取它们基本信息的方法。在java技术中,目录也是一个文件。你可以创建一个代表目录的文件,然后用它定义另一个文件:
File myFile;
myFile = new File("FileName");
myFile = new File("/", "FileName");
File myDir = new File("/");
myFile = new File(myDir, "FileName");
你所使用的构造函数经常取决于你所使用的其他文件对象。例如,如果你在你的应用程序中只使用一个文件,那么就会使用第一个构造函数。如果你使用一个公共目录中的若干文件,那么使用第二个或者第三个构造函数可能更容易。
File类提供了独立于平台的方法来操作由本地文件系统维护的文件。然而它不允许你存取文件的内容。
注意:你可以使用一个File对象来代替一个String作为FileInputStream和FileOutputStream对象的构造函数参数。这是一种推荐方法,因为它独立于本地文件系统的约定。
文件测试和工具
当你创建一个File对象后,你可以使用下面任何一种方法来获取有关文件的信息:
文件名:
String getName()
String getPath()
String getAbsolutePath()
String getParent()
boolean renameTo(File newName)
文件测试:
boolean exists()
boolean canWrite()
boolean canRead()
boolean isFile()
boolean isDirectory()
boolean isAbsolute()
通用文件信息和工具:
long lastModified()
long length()
boolean delete()
目录工具:
boolean mkdir()
String[] list()
请看下例:
import java.io.*;
class TestReader {
public static void main(String[] args) {
//读取当前目录下的,该类的原文件
File f = new File("TestReader.java");
//输出到当前目录下的out.java,系统会自动创建该文件
File f1 = new File("out.java");
FileReader fr = null;
FileWriter fw = null;
BufferedReader br = null;
PrintWriter pw = null;
try {
fr = new FileReader(f);
br = new BufferedReader(fr);
fw = new FileWriter(f1);
pw = new PrintWriter(fw, true);//true 代表自动刷新到磁盘里
String ss = br.readLine();
while (ss != null && !ss.equals("exit")) {
pw.println(ss);
ss = br.readLine();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//不管发生不发生异常,都要进行IO流的关闭
try {
//防止发生空指针异常,也就是说在创建文件IO流之前发生异常。
if (br != null)
br.close();
if (pw != null)
pw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// 以上是关闭IO流最完整的代码
}
}
运行完之后,会在当前目录下生成out.java文件,跟上面的源文件一样。
例5
问题的描述:
通过控制台写数据到文件里
解决方案:
1,建立控制台的输入流
2,建立文件的输出流
请看下例:
import java.io.*;
class TestKWF {
public static void main(String[] args) {
File file = new File("keyout.java");
BufferedReader br = null;
// 要习惯性的给声明的引用类型变量初始化为null
PrintWriter pw = null;
try {
br = new BufferedReader(new InputStreamReader(System.in));
pw = new PrintWriter(new FileWriter(file));
System.out.println("按 ctrl+c 键 或者输入exit 退出程序!");
String s = null;
s = br.readLine();
// 如果按 ctrl+c 键,那么s==null,所以要先进行s!=null判断,不然
// 会出现空指针异常(调用s.equals("exit"))
while (s != null && !s.equals("exit")) {
pw.println(s);
s = br.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
if (pw != null)
pw.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
运行完之后,会在当前目录下生成keyout.java文件,跟控制台输入的一样。
例6
问题的描述:
String 类的使用
解决方案:
String 对象是一个不可变的统一编码字符串。该类是JDK中最特殊的一个类。只要一个String对象值改变,系统会在内存堆里寻找新的空间来存放改变后的值。
请看下例:
class TestString {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "abc";
/*
* 如果该成 String s2 = new String("abc"); 会在内存中再生成一个"abc"对象 那么将第一次将输出!=
* 如果要想输出== 把(s1 == s2)改成(s1.equals(s2)) ==只能判断基本类型的值和引用类型的地址相等不相等
* equals方法可以判断引用类型的值相等不相等。
*/
if (s1 == s2) // 地址相等的判断
System.out.println("==");
else
System.out.println("!=");
s2 = s2 + "d"; // 改变对象"abc"的值
if (s1 == s2) // 地址相等的判断,如果输出!= 说明s2的地址改变了。
System.out.println("==");
else
System.out.println("!=");
}
}
译和运行的结果为:
==
!=
例7
Set容器
问题的描述:
Set容器的使用
解决方案:
在下面的例题中,程序声明了一个Collections API的Set 型对象,并且用它的子类HashSet初始化它。然后向Set中添加元素,打印结果。
请看下例:
import java.util.*;
public class TestSet {
public static void main(String[] args) {
Set set = new HashSet();
set.add("abc");
set.add("abd");
set.add("abe");
set.add(new Integer(4));
set.add("abe"); // 插入了相同的数据,所以会失败
set.add(new Integer(4)); // 同上
System.out.println(set);
}
}
编译和运行的结果为:
[4,abd,abc,abe]
从结果可以看出Set容器的特点:不能保存重复的数据,而且保存的是无序的数
请思考下面的问题:这里的重复数据是根据什么判断两个数据是否是同一个数据?
是由对象的hashCode()和equals()方法共同决定的。
请看下例:
import java.util.*;
class TestSet1 {
public static void main(String[] args) {
HashSet hs = new HashSet();
// 保存了10个数据
for (int i = 0; i < 10; i++)
hs.add(new Data());
// 只打印一个数据,如果Data没有覆盖hashCode()、equals()其中一个方法,那么会输出10个数据
System.out.println(hs);
}
}
class Data {
// 覆盖hashCode()方法,得到一样的hashcode
public int hashCode() {
return 12;
}
// 覆盖equals()方法,是每个对象比较相等
public boolean equals(Object o) {
return true;
}
}
输出结果为:
[Data@c]
来分享 Java视频教程