二、Java基础--02
作为本人首篇黑马技术博客有必要交代一下背景。个人理解博客的用作在于于己在于交流,于他在于学习,在交流学习中共同成长。下面进入正题。本文主要是介绍在做黑马入门测试时的一些问题(这个应该不是泄露题库吧)。
本文只要是讲述黑马程序员基础测试题的6-10题,回过头来分析明显感觉到难度的上升,考察的级别也有所提升,尤其是第9、第10,而且有一定的实用性,后文会进行分析。
第六题是关于面向对象的继承的基本知识,这个题属于大路边上的题,没有难度,这篇博客只给出原题,我会在后续的博客中进行更深入的分析。题目描述:
声明类Person,包含2个成员变量:name、age。定义函数sayHello(),调用时输出:我叫***,今年***岁了。声明类Chinese继承Person。
第七题是关于数组去重的,题目描述:
数组去重复,例如: 原始数组是{4,2,4,6,1,2,4,7,8},得到结果{4,2,6,1,7,8}
这个题其实没有什么难度,但是有一个特点是输出的结果不是按照排序之后输出而是只是将原来的数组中重复的提出,但是顺序不变。刚开始我的想法是先借助Arrays.sort(),将数组排序然后前后进行比较,如果后一个和前一个相同则不输出,否则就输出,虽然可以实现去重,但是顺序改变了,显然不满足题目要求,具体程序实现如下:
@Test
public void testMain()
{
int a[]={4,2,4,6,1,2,4,7,8};
Arrays.sort(a);//将数组从小到大进行排序
moveTheSame(a);//调用去重函数
}
private void moveTheSame(int[] a) {
for(int i=0;i<a.length-1;i++)
{
if(a[i]!=a[i+1])
System.out.print(a[i]);
}
if(a[a.length-2]!=a[a.length-1])//处理边界情况,
System.out.println(a[a.length-1]);
}
另外一种做法是通过Set集合元素不可重复的属性进行。具体实现如下:
@Test
public void testMain()
{
int a[]={4,2,4,6,1,2,4,7,8};
int b[]=moveTheSame(a);//数组去重
for(int i:b)//遍历输出
System.out.print(i);
}
private int[] moveTheSame(int[] a)
{
Set<Integer> mySet=new HashSet<Integer>();
for(int i=0;i<a.length;i++)//将元素放入Set集合
{
mySet.add(a[i]);
}
Object[] o=mySet.toArray();
int b[]=new int[o.length];
for(int i=0;i<b.length;i++)//为了保证与原数组类型一致,如果只是输出的话直接返回Object就行
b[i]=Integer.parseInt(o[i].toString());
return b;//返回原数组类型
}
还有一种做法是将数组转化为String,然后依次进行比较(和第一个相似),但是考虑到大于10的数,所以放弃,但是思想有借鉴价值,下面的结果就是借鉴这个原理得到的
public static void main(String[] args) {
int a[] = { 4, 2, 4, 6, 1, 2, 4, 7, 8 };
int b[] = moveTheSame(a);// 调用数组去重方法
for (int i = 0; i < b.length; i++)
// 按原格式输出
if (i != b.length - 1)
System.out.print(b[i] + ",");
else
System.out.print(b[i]);
}
private static int[] moveTheSame(int[] a) {
List<Integer> list = new ArrayList<Integer>();// 声明一个ArrayList,默认值为null
for (int i = 0; i < a.length; i++)
// 依次编译数组,如果list中不包含当前的元素则将当前元素加入到list,如果包含则忽略。
if (!list.toString().contains(a[i] + ""))
list.add(a[i]);
int b[] = new int[list.size()];
Object o[] = list.toArray();// 将list中元素转化为数组
for (int i = 0; i < b.length; i++)
// 同样是为了保证与原数组类型一直
b[i] = Integer.parseInt(o[i].toString());
return b;
}
上面介绍了三种方法,但是输出结果都是已排序和题目要求矛盾,上面介绍第三中方法,这种方法思想借助上面的分析,其实也是通过上面的分析得出的最终解决方案。我们在做一些算法题目往往不是一步就成功,而是将大问题分解为小问题一步步去实现。
总结:
1,观察数组特点得知数组的输出结果是一个无序数组,所以使用将数组转化为set集合的方案
(或者先借助Arrays.sort()进行排序,然后进行判断)行不通。
2,考虑将数组转化为Stirng类型,借助中间变量去判断中间变量中是否包含当前迭代元素,
如果包含则忽略,不包含则将当前元素加入到中间变量,考虑到大于10的数据,放弃本方案
3,直接借助List,如果中间变量List中存在当前变量则忽略,不存在则加入list中,
可以解决上面出现的问题。但是注意返回的类型应该保持与原来数组类型一致,
因此迭代将每个Integer元素转化为int,然后返回int数组
大家可以看到简简单单一道题有着这么大的工作量,当你写的多了对程序的设计就很快做出了,一步一步来才是王道。
第八题也是考察的只是是内部类已经其调用,这也是一个很重要的一个知识点,由于考察的形式简单,在此也就简单的分析。题目描述如下:
在打印语句中如何打印这3个x变量?
class A // 外部类
{
int x = 1;
class B// 内部类
{
int x = 2;// 内部类属性
void func() //内部类成员方法
{
int x = 3;
System.out.println(x);
}
}
}
参考解决方案:
A a=new A();//建立外部类的实例对象
System.out.println(a.x);//通过外部类的实例对象调用外部类的属性
A.B b=a.new B();//实例化内部类的对象
System.out.println(b.x);//通过内部类的实例对象调用内部类的属性
b.func();//通过内部类的对象调用内部类的成员方法
第九题也是我对我启发特别大的一个题目,是关于IO流的,之前学习过但是不是很熟悉,我的了解IO无非就是文件读写,也就是上传下载。在做JavaWeb项目时通常会用到工具包,所以对IO的重要性就淡化了好多,但是这道题给了我很多启发。题目描述如下:
编写程序,将指定目录下所有.java文件拷贝到另一个目的中,并将扩展名改为.txt
思路:
1.遍历指定目录的文件夹,并将以.java结尾的文件封装到list中,以便后续操作。
2.创建一个目的目录myDir
3.遍历list,指定文件目录为myDir,文件名为源文件名,后缀为.txt
程序实现如下:
public static void main(String[] args) throws IOException {
File dir = new File("F:\\a");
List<File> list = new ArrayList<File>();
file2List(dir, list);
list2TextbyChar(list);
}
// 遍历指定目录下的所有文件,并将*.java文件封装到List中
static void file2List(File dir, List<File> list) {
File files[] = dir.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {// 如果当前文件为目录,递归遍历
file2List(files[i], list);
} else if (files[i].toString().endsWith(".java"))// 如果当前文件是以.java结尾,也就是java文件那么将该文件添加到list中
list.add(files[i]);
}
}
// 遍历封装了java文件的list,并将对应信息写到指定目录下对应的*.txt文件中
static void list2TextbyChar(List<File> list) throws IOException {
File f = new File("E:\\myDir");// 指定目标文件目录,如果不存在就新建该目录
f.mkdirs();
for (int i = 0; i < list.size(); i++) {
// 获取目标文件路径,已经源文件的文件名,将.java替换为.txt
String fileName = f+ "\\"+
list.get(i).getName().toString().substring(0,list.get(i).getName().toString().length() - 5)+ ".txt";
FileReader fr = new FileReader(list.get(i).getAbsoluteFile());// 读取每个文本文件的信息
FileWriter fw = new FileWriter(fileName);// 创建同名目录
int ch = 0;
while ((ch = fr.read()) != -1) {
fw.write(ch);
}
fw.close();
fr.close();
}
}
说这个题对我的启发大是因为有一个问题一直困扰着我,就是本人保存文件都是按照月份进行的但是时间长了去找文件就会很麻烦有时很长时间都找不到,很是纠结,在这个题目的启发下我将磁盘上所有文件,按照后缀名进行分类。这样对我来说带来了很大便利,比如我要找JDK的API,那么我只需去chm文件夹下找就ok了。下面程序演示我的实现:
public static void main(String[] args) throws IOException {
File dir=new File("E:\\");
List<File> list = new ArrayList<File>();
file2List(dir, list);
list2TextbyByte(list);
}
// 遍历指定目录下的所有文件,并将*.java文件封装到List中
static void file2List(File dir, List<File> list) {
File files[] = dir.listFiles();
int b = 0;
try {
for (int i = 0; i < files.length; i++) {
/*
if (!files[i].getAbsolutePath().contains("$")
&& !files[i].getAbsolutePath().contains("System")
&& !files[i].getAbsolutePath().contains("RECYCLER")
&& !files[i].getAbsolutePath().contains("Documents and Settings")
&&!files[i].getAbsolutePath().contains("Program"))*/
if (!files[i].isHidden())//这个是为了防止读取系统关键文件(会禁止访问而造成异常)
{
b = i;
if ( files[i].isDirectory()) {
file2List(files[i], list);
}
if (files[i].getAbsolutePath().endsWith(".chm"))
list.add(files[i]);
}
else
continue;
}
} catch (Exception e) {
System.out.println(files[b].getAbsolutePath());
e.printStackTrace();
}
}
static void list2TextbyByte(List<File> list) throws IOException {
File f = new File("C:\\mychm");// 知道目标文件目录,如果不存在就新建该目录
f.mkdirs();
for (int i = 0; i < list.size(); i++) {
// 获取目标文件路径,已经源文件的文件名
String fileName = f + "\\" + list.get(i).getName().toString();
FileInputStream fis = new FileInputStream(list.get(i)
.getAbsoluteFile());
FileOutputStream fos = new FileOutputStream(fileName);
int ch = 0;
byte by[] = new byte[1024 * 1024];
while ((ch = fis.read(by)) != -1) {
fos.write(by, 0, ch);
}
fos.close();
fis.close();
}
}
第十题是关于字节流的,在一份试卷中有两个题而且是压轴题是用到了IO,由此可见IO的重要性,题目描述如下:
编写函数,从一个字符串中按字节数截取一部分,但不能截取出半个中文(GBK码表)
例如:从"HM程序员"中截取2个字节是"HM",截取4个则是"HM程",截取3个字节也要是"HM"而不要出现半个中文
分析:在GBK下,一个英文字符为一个字节,一个汉字为两个字节。
处理时可以分情况进行处理:
1.读取字节时按照GBK的方式读取
2.用变量count控制读取的次数,当达到截取长度时break,结束程序
3.定义一个长度为1个字节的byte数组by[],用于处理单字节的内容,同时负责临时缓存半个中文的字符
4.定义一个长度为2个字节的byte数组by2[],勇于处理中文。
程序实现如下:
public static void main(String[] args) throws IOException {
mychar();
}
static void mychar() throws IOException {
String s = "HM程序员";// 初始化字符串
// 将字符串按字节(GBk)放在InputStream中
InputStream is = new ByteArrayInputStream(s.getBytes("GBK"));
// 定义需要截取字节的长度,以及给计数标记赋初值0,用以控制跳出条件
int n = 0, count = 0;
Scanner sc = new Scanner(System.in);
System.out.print("请输入截取字节长度:");
// 接收要截取的字节长度
n = sc.nextInt();
int len = 0;
// 用于处理长度为1的字符
byte[] by = new byte[1];
// 用于处理长度为2的字符
byte[] by2 = new byte[2];
int i = 0;
while ((len = is.read(by)) != -1)
{
if (!(by[0] < 0))// 字符
{
System.out.print((char) by[0]);// 将一个字节强转为字符并输出
} else if (i < 1)// 处理半个中文
{
i++;
by2[0] = by[0];
} else // 当i>0时表示处理汉子的低位字节,两个字节为一个汉字
{
by2[1] = by[0];
System.out.print(new String(by2));// 将分开的两个字节合成为一个中文字符并输出
by2 = new byte[2];
i = 0;
}
count++;
if (count == n)
break;
}
}
到此,试卷的讲解结束,谢谢您的阅读。
二、Java基础--02的更多相关文章
- java基础-02数据类型
基本类型 整数 byte byte 数据类型是8位.有符号的,以二进制补码表示的整数 最小值是 -128(-2^7) 最大值是 127(2^7-1) 默认值是 0 byte 类型用在大型数组中节约空间 ...
- Java基础02 方法与数据成员
作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 在Java基础01 从HelloWorld到面向对象,我们初步了解了对象(obje ...
- [Java面试二]Java基础知识精华部分.
一:java概述(快速浏览): 1991 年Sun公司的James Gosling等人开始开发名称为 Oak 的语言,希望用于控制嵌入在有线电视交换盒.PDA等的微处理器: 1994年将Oak语言更名 ...
- 面试题(二)—Java基础(下)
一.进程和线程 进程 (1)正在运行的程序,是系统进行资源分配和调用的独立单位. (2)每一个进程都有它自己的内存空间和系统资源. 线程 (1)是进程中的一条执行路径. (2)一个进程如果只有一条执行 ...
- 实验二 Java基础(数据/表达式、判定/循环语句)
实验二 (一)实验内容 编写简单的计算器,完成加减乘除模运算. 要求从键盘输入两个数,使用判定语句选择一种操作,计算结果后输出,然后使用判定和循环语句选择继续计算还是退出. 编写测试代码,测试验证. ...
- Java 基础02
参照:https://www.cnblogs.com/ZXF6/p/11530009.html 类和对象 /** * java 中的类和对象 * * 一.局部变量的作用域. * * 二.面向对象的概述 ...
- java基础02 数据类型转
一.回答问题 float f1 = 6.66f; float f2 = (float) 6.67; f1==f2? /** * * @author sun * */ public class Demo ...
- Java基础学习笔记二 Java基础语法
注释 注释用来解释和说明程序的文字,注释是不会被执行的. 单行注释 //这是一条单行注释 public int i; 多行注释 /* 这是 * 一段注释, * 它跨越了多个行 */ public vo ...
- java基础02
使用 myeclipse写第一个java程序 之后 右键 点击 src 创建 Class /** * package:包的声明! * 代表我们当前的java源文件在项目中的位置! * 必须位于除了 ...
随机推荐
- Watering Grass
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85904#problem/E 题意: 给定一条草坪,草坪上有n个喷水装置.草坪长 ...
- bootstrap学习笔记之二
学习表单时还是有些吃力的,主要感觉有些结构有些复杂,没有自己亲手去操作就感觉似懂非懂,所以还得自己亲手测一下. 现在开始按钮的学习. 可作为按钮使用的标签和元素有: <a>.<bu ...
- 导出查询结果到excle
实现功能 输入查询结果 点击导出查询结果 导出到excle表.
- ajax实现文件上传
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- JSTL 核心标签库 使用(C标签)
JSTL 核心标签库标签共有13个,功能上分为4类: 1.表达式控制标签:out.set.remove.catch 2.流程控制标签:if.choose.when.otherwise 3.循环标签:f ...
- Unity学习疑问记录之Apply Root Motion
Should we control the character's position from the animation itself or from script. 如果我们勾选了Animator ...
- 常用SQLPLUS工具命令
有两个 EMPNO ENAME SAL的列标题 满 14行 为一个标题行 列行重叠了 虽然上述是修改了 linesize 的值,但是仍然没有改变 登录框的宽度,下面是修改 ...
- Jquery的命名冲突
$是Jquery的别名,为了编码方便,我们可以使用$符号来调用Jquery的函数.然而,当我们引入多个JS库的时候,如果另外一个库中也引用了$符号作为别名的话,那么我们在使用$符号的时候,由于同一个作 ...
- Apache Spark技术实战之5 -- SparkR的安装及使用
欢迎转载,转载请注明出处,徽沪一郎. 概要 根据论坛上的信息,在Sparkrelease计划中,在Spark 1.3中有将SparkR纳入到发行版的可能.本文就提前展示一下如何安装及使用SparkR. ...
- BigPipe学习研究
BigPipe学习研究 from: http://www.searchtb.com/2011/04/an-introduction-to-bigpipe.html 1. 技术背景 FaceBook ...