二、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源文件在项目中的位置! * 必须位于除了 ...
随机推荐
- NodeJS优缺点及适用场景讨论
概述:NodeJS宣称其目标是“旨在提供一种简单的构建可伸缩网络程序的方法”,那么它的出现是为了解决什么问题呢,它有什么优缺点以及它适用于什么场景呢? 本文就个人使用经验对这些问题进行探讨. 一. N ...
- jquery .post .get中文参数乱码解决方法详解
jquery默认的编码为utf-8,做项目时有时处于项目需要用到ajax提交中文参数,乱码问题就很头疼了,折腾了许久终于弄出来了.为了便于传输,我们首先将需要用到的参数用javascript自带的函数 ...
- 【android studio】解决android studio drawable新建项目时只有一个drawable目录的问题
概述 android studio默认新建Module时,只新建一个drawable目录,并不会新建适配不同分辨率的drawable目录.但其实,这是可以设置的.有以下两种方法: 方法1 详细步骤 进 ...
- [LintCode] Valid Number 验证数字
Validate if a given string is numeric. Have you met this question in a real interview? Yes Example & ...
- Python 3.x下消除print()自动换行
Python 2.x下的print语句在输出字符串之后会默认换行,如果不希望换行,只要在语句最后加一个“,”即可.但是在Python 3.x下,print()变成内置函数,加“,”的老方法就行不通了. ...
- jQuery判断元素是否存在方法总结
在jquery中判断元素是否存在我们可使用$("#div").length > 0)来判断了,意思就是判断元素长度了,如果没有肯定是不存在的哦,下面我来介绍介绍. 使用传统j ...
- Python数据类型(3)
字符串(str):单引号''.双引号""嵌套使用,可以不使用转义字符:'abc"dd"ef'."acc'd'12",字符串不可以是多行的三单 ...
- Spinner的深入学习
简介: spinner是一个列表选择框,会在用户选择后,展示一个列表供用户进行选择.Spinner是ViewGroup的间接子类,它和其他的Android控件一样,数据需要使用Adapter进行封装. ...
- BLOB
BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器.在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型.BLOB是一个大文件,典型的BLOB ...
- node exports与 module.exports的区别
你肯定非常熟悉nodejs模块中的exports对象,你可以用它创建你的模块.例如:(假设这是rocker.js文件) exports.name = function() { console.log( ...