集合类的使用

收集

收集(或容器)是代表一个对象组的单个对象,其它对象被认为是它的元素。收集用于处理多种类型对象的问题,所有的类型都有一个特殊的种类(也就是说,它们都是从一个共同父类继承来的)。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视频教程
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值