黑马程序员——IO流8:IO流综合练习

------ Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

IO流8:IO流综合练习

需求:

        有五个学生,每个学生有3门课的成绩。

        从键盘输入以上数据(包括姓名,三门课成绩)。

        输入的格式:张三,75,83,90,三门课总成绩(需计算得出)。

        最终把学生个人信息的和三门课总成绩按照高低顺序存放在磁盘文件“stud.txt”中。

思想:

        (1) 定义学生类和用于操作学生类的工具类;

        (2) 通过操作学生工具类,获取从键盘录入的学生信息和成绩,并将这些信息封装为学生对象;

        (3) 将这些学生对象存储到一个集合中,便于对学生对象进行操作。由于需要对这些学生对象按照总成绩进行排序,因此可以使用TreeSet集合;

        (4) 将集合中存储的学生对象循环取出,并将学生信息写入到一个文件中。

思想分步解析与代码实现:

(1)  定义学生类——Student

类的声明:

        由于需要在学生之间通过总成绩进行比较,因此应该令Student类实现Comparable接口,并为其定义泛型——Student。

成员变量:

        通过定义成员变量表示学生的各种基本信息,比如姓名name(String类型),各科成绩(int型):数学math、语文ch、英语en等等,以及各科总成绩(int型)sum。

成员方法:

        首先是用于返回各个成员变量的方法。为方便演示,以下代码中不再定义成员变量的对应的set方法,并且仅定义返回name和sum的get方法。

        其次,为便于将Student对象存储于HashSet或HashMap集合中,为Student类定义hashCode和equals方法。

        第三,也是最重要的方法是,复写Comparable接口的compareTo方法,主要条件为三个总成绩,次要条件为姓名对应字符串自然排序。

        最后,定义将学生信息转换为字符串返回的toString方法。

以下是这一部分的代码,

代码1:

//定义学生类,因为需要按照成绩高低进行排序
//因此令学生类实现Comparable接口
class Student implementsComparable<Student>
{
	private String name;
	private int math,ch,en,sum;
	Student(String name, int math, int ch, int en)
	{
		this.name= name;
		this.math= math;
		this.ch= ch;
		this.en= en;
 
		sum = math + ch + en;
	}
 
	public String getName()
	{
		return name;
	}
	public int getSum()
	{
		return sum;
	}
 
	//为方便后期将Student对象存储到HashSet或HashMap集合中
	//为其定义HashCode和equals方法
	public int hashCode()
	{
		return name.hashcCode() + sum * 27;
	}
	public boolean equals(Object obj)
	{
		if(! obj instanceof Student)
			throw new IllegalArgumentException("所传参数类型不匹配!");
 
		Student stu = (Student)obj;
 
		return name.equals(stu.getName()) && age == stu.getAge();
	}
 
	//用于比较两Student类的compareTo方法
	public int compareTo(Student stu)
	{
		int value = new Integer(sum).compareTo(new Integer(stu.getSum()));
		if(value == 0)
			return name.compareTo(stu.getName());
 
		return value;
	}
 
	public String toString()
	{
		return "student["+name+", "+math+", "+ch+","+en+", "+sum+"]";
	}
}

(2)  定义用于操作学生类的工具类——StuInfoTools

        由于工具类中并不涉及操作该类特有数据,因此StuInfoTools的所有方法均为静态方法。

方法一:获取存有若干学生对象TreeSet集合的方法——getStudents:

        通过键盘录入的方式,接受字符串类型的学生信息,并将表示学生信息的字符串按照“,”进行分割,并将成绩转换为int型值以后,封装为Student对象,并存储到TreeSet集合中。最终该方法将返回该集合。

        如果希望既能按照默认顺序排序(按总成绩从小到大),又能按照用户指定的其他排序方式对Student对象进行排序,为getStudents方法定义重载方法。其中一个getStudents方法可以接受一个比较器对象(Comparator接口实现类实例对象),那么在方法内创建TreeSet集合对象前,进行判断:如果传入参数(比较器对象)为null,则创建空参数集合对象;否则为集合对象初始化传入的比较器;另一个getStudents方法为空参数方法,其方法体为调用含参getStudents方法的同时传入参数为null。

方法二:将集合中学生对象的信息循环写入到指定路径下的文件中。

        创建缓冲字符写入流对象,并与指定文件进行关联。通过foreach对存有学生对象的Set集合进行遍历,同时将每个学生的学生信息(调用toString方法)写入到文件中。

这一部分代码,

代码2:

//定义用于操作学生对象的工具类——StuInfoTools
class StuInfoTools
{
	public static Set<Student>getStudents() throws IOException
	{
		getStudents(null);
	}
	public static Set<Student> getStudents(Comparator<Student> cmp) throwsIOException
	{
		//同于存储Student对象的TreeSet集合
		//通过比较器判断需要创建的集合是按默认顺序排序还是按指定顺序排序
		Set<Student>stus = null;
		if(cmp == null)
			stus = new TreeSet<Student>();
		else
			stus = new TreeSet<Student>(cmp);
 
		BufferedReader bufr =
			new BufferedReader(new InputStreamReader(System.in));
             
		Student stu = null;
		String line = null;
		while((line= bufr.readLine()) != null)
		{
			//定义结束标记
			if("over".equals(line))
				break;
 
			String[] infos = line.split(",");
 
			//将分割并转换类型得到的学生信息封装为Student对象
			stu = new Student(infos[0],
			Integer.parseInt(infos[1]),
			Integer.parseInt(infos[2]),
			Integer.parseInt(infos[3]));
 
			stus.add(stu);
		}
 
		return stus;
	}
	public static void write2File(Set<Student> stus,File file) throws IOException
	{
		BufferedWriter bufw =
			new BufferedWriter(new FileWriter(file));
 
		for(Student stu : stus)
		{
			bufw.write(stu.toString());
			bufw.newLine();
			bufw.flush();
		}
 
		bufw.close();
	}
}

(3)  测试类——IOTest

首先创建用于写入学生信息的File对象,并与路径和文件名关联。

其次,通过Collections工具类的reverseOrder方法,获得用于强行逆转集合默认排序顺序的比较器对象(这一步骤为可选步骤);

第三,通过调用StuInfoTools工具类的getStudents方法,创建一个泛型为Student的TreeSet集合对象,如有需要可为其初始化第二步创建的比较器对象。

最终,调用StuInfoTools工具类的write2File方法,将学生信息写入到第一步创建的File对象关联的文件中。

这一部分代码为,

代码3:

class IOTest
{
	public static void main(String[] args) throws IOException
	{
		File file =
			new File("E:\\ StusInfo.txt");
		if(!file.exists())
			file.createNewFile();
 
		Comparator<Student> cmp = Collections.reverseOrder();
 
		Set<Student> stus = StuInfoTools.getStudents(cmp);
		StuInfoTools.write2File(stus,file);
	}
}
执行以上代码后,在控制台中输入以下信息:

David,87,71,88

Lucy,67,81,77

Kate,69,90,87

Peter,59,71,65

over

则在关联文件中的内容为:

student[Kate, 69, 90, 87]              246

student[David, 87, 71, 88]     246

student[Lucy, 67, 81, 77]      225

student[Peter, 59, 71, 65]      195


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值