第二次博客总结
前言:
这一次题目及难度比上次高了好多,差不多每个题目都要动脑筋思考,很多题目都用到了继承与多态,体现了面向对象的思考,数据域的封装大多都会了,还有抽象类的用法,求个日期都有几种不同的解法,有类与类之间聚合关系的,还有继承关系的,还可以用到接口,java,还是博大精深呀。越学越能感受到它的精妙所在。我总结了以下几点:
一.简单性:
Java是纯面向对象语言,语法简单明了,易于掌握。
Java使用接口取代了多重继承,并且取消了指针,因为多重继承和指针会使程序变得复杂。
Java还会自动地收集内存垃圾,使得内存管理变得更为简单。
Java还提供了丰富的类库、API文档以及第三方开发包,还有大量Java的开源项目。
二.面向对象性:
面向对象性事Java语言的基础。
java语言提倡“万物皆对象”,语法中不能在类外面定义单独的数据和函数。
Java语言最外部的数据类型是对象,所有的元素都要通过类和对象来访问。
三.分布性:
Java的分布性包括:1.操作分布。2.数据分布
⑴操作分布:即在多个不同的主机上不知相关操作。
⑵数据分布:将数据分别存放在不同的主机上,这些主机是网络中的不同成员。
四.可移植性:
Java程序具有与体系结构无关的特性。
Java的类库也提供了针对不同平台的接口,所有这些类库也可以被移植。
五.安全性
Java语言删除了类C语言的指针和内存释放等语法,有效地避免了用户对内存的非法操作
Java程序代码要经过代码程序校验、指针校验等很多测试步骤才能够运行。所以未经允许的Java程序不能出现损害系统平台的行为。
Java可以编写出防病毒和防修改系统。
六.健壮性
Java会检查程序在编码和运行时的错误,并消除错误。
七.多线程性。
Java应用程序可以在同一时间并行执行多项任务。而且相应的同步机制可以保证不同线程能够正确地共享数据。
八.高性能性
Java编译后的字节码是在解释器中运行的,所以它的速度较多数交互式运用程序提高了很多。
九.动态性
Java可以动态调整库中方法和增加变量,并且客户端不需要任何更改。在Java中进行动态调整是非常简单和直接。
①题目集4(7-2)、题目集5(7-4)两种日期类聚合设计的优劣比较:
题目集4(7-2)


部分代码如下
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int year = 0;
int month = 0;
int day = 0;
int choice = input.nextInt();
if (choice == 1) { // test getNextNDays method
int m = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
m = input.nextInt();
if (m < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
System.out.println(date.getNextNDays(m).showDate());
} else if (choice == 2) { // test getPreviousNDays method
int n = 0;
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
DateUtil date = new DateUtil(year, month, day);
if (!date.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
n = input.nextInt();
if (n < 0) {
System.out.println("Wrong Format");
System.exit(0);
}
System.out.print(
date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
System.out.println(date.getPreviousNDays(n).showDate());
} else if (choice == 3) { //test getDaysofDates method
year = Integer.parseInt(input.next());
month = Integer.parseInt(input.next());
day = Integer.parseInt(input.next());
int anotherYear = Integer.parseInt(input.next());
int anotherMonth = Integer.parseInt(input.next());
int anotherDay = Integer.parseInt(input.next());
DateUtil fromDate = new DateUtil(year, month, day);
DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);
if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
System.out.println("The days between " + fromDate.showDate() +
" and " + toDate.showDate() + " are:"
+ fromDate.getDaysofDates(toDate));
} else {
System.out.println("Wrong Format");
System.exit(0);
}
}
else{
System.out.println("Wrong Format");
System.exit(0);
}
}
}
class DateUtil {
private int year;
private int month;
private int day;
public DateUtil(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
public DateUtil(){}
public void setYear(int year) {
this.year = year;
}
public void setMonth(int month) {
this.month = month;
}
public void setDay(int day) {
this.day = day;
}
public int getYear() {
return year;
}
public int getMonth() {
return month;
}
public int getDay() {
return day;
}题目集5(7-4)


部分代码如下
Scanner input = new Scanner(System.in);
int n = input.nextInt();
switch (n) {
case 1:
int year = input.nextInt();
Year years = new Year( year);
int month = input.nextInt();
Month months = new Month(month);
int day = input.nextInt();
Day days = new Day(day);
int m = input.nextInt();
DateUtil date = new DateUtil(year,month,day);
if(!date.vaid(m,year,month,day)) {
System.out.println("Wrong Format");
System.exit(m);
}
System.out.print(date.getYear(year) + "-" + date.getMonth(month) + "-" + date.getDay(day) + " next " + m + " days is:");
System.out.println(date.getNextNDays(m,year,month,day) + "-"+date.getNextNDay(m,year,month,day)+"-"+date.getNextNDa(m,year,month,day));
case 2:
int year2= input.nextInt();
Year years2 = new Year( year2);
int month2= input.nextInt();
Month months2= new Month(month2);
int day2 = input.nextInt();
Day days2 = new Day(day2);
int m2 = input.nextInt();
DateUtil date2 = new DateUtil(year2,month2,day2);
if(!date2.vaid(m2,year2,month2,day2)) {
System.out.println("Wrong Format");
System.exit(m2);
}
System.out.print(date2.getYear(year2) + "-" + date2.getMonth(month2) + "-" + date2.getDay(day2) + " previous " + m2 + " days is:");
System.out.println(date2.getPreviousNDays(m2,year2,month2,day2) + "-"+date2.getPreviousNDay(m2,year2,month2,day2)+"-"+date2.getPreviousNDa(m2,year2,month2,day2));
case 3:
DateUtil date3 = new DateUtil();
int a = input.nextInt();
int b = input.nextInt();
int c = input.nextInt();
int d = input.nextInt();
int e = input.nextInt();
int f = input.nextInt();
int D = date3.getdays(a,b,c,d,e,f);
if(!date3.vaid2(a,b,c,d,e,f)) {
System.out.println("Wrong Format");
System.exit(a);
}
System.out.println("The days between " + a+"-"+b+"-"+c + " and " + d+"-"+e+"-"+f+ " are:"
+ D);
}
input.close();
if(n > 3||n<0) {
System.out.println("Wrong Format");
}
}
}
class DateUtil{
public Year year;
public Month month;
public Day day;
public int daymax[] = {31,28,31,30,31,
30,31,31,30,31,30,31};
public DateUtil() {
super();
// TODO Auto-generated constructor stub
}
public DateUtil(int year, int month, int day) {
super();
}
public int getYear(int year) {
return year;
}
public void setYear(Year year) {
this.year = year;
}
public int getMonth(int month) {
return month;
}
public void setMonth(Month month) {
this.month = month;
}
public int getDay(int day) {
return day;
}
public void setDay(Day day) {
this.day = day;
}
public void setmin() {
for(int n = 0;n<12;n++) {
daymax[n] = 1;
}
}
public int setmax(int year,int month) {
int days = daymax[month - 1];
if (month == 2 && isLeapYear(year)) {
days = 29;
}
return days;
}
public boolean isLeapYear(int value) {
boolean year = false;
if((value%4==0&&value%100!=0)||value%400==0) {
year = true;
}
return year;
}
public boolean vaid(int m,int year,int month,int day) {
boolean a = false;
if(m > 0&&year>=1820&&year<=2020&&month>0&&month<13&&day<=setmax(year, month)&&day>0)
a = true;
return a;
}
public int getNextNDays(int n,int year,int month,int day)
{
for (int i = 0; i < n; i++) {
day++;
if (day > setmax(year, month)) {
day = 1;
month++;
if (month > 12) {
month = 1;
year++;
}
}
}
return year;
}
public int getNextNDay(int n,int year,int month,int day)
{
for (int i = 0; i < n; i++) {
day++;
if (day > setmax(year, month)) {
day = 1;
month++;
if (month > 12) {
month = 1;
year++;
}
}
}
return month;
}
public int getNextNDa(int n,int year,int month,int day)
{
for (int i = 0; i < n; i++) {
day++;
if (day > setmax(year, month)) {
day = 1;
month++;
if (month > 12) {
month = 1;
year++;
}
}
}
return day;
}
public int getPreviousNDays(int n,int year,int month,int day)
{
for (int i = 0; i < n; i++) {
day--;
if (day < 1) {
month--;
if (month < 1) {
month = 12;
year--;
}
day+=setmax(year, month);
}
}
return year;
}
public int getPreviousNDay(in
两种方法都能完成所要求的东西,但明显聚合类的方法更实用,更简洁,就能体现面向对象的意义,重点是靠业务类,而不是思考实体类,实体类是很简单的,要思考的是如何实现实体类。这样的程序性能会更好,也更方便测试和维护。例如图中,题目集四的,类的关系是一个连的一个的,随便哪一个出错程序就会运行不了,而在题目集五中,应用类不直接和main类相连接,但是和dateutil相关,各司其职。
②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用
题目集4(7-3)



部分代码如下
Scanner input = new Scanner(System.in);
int n = input.nextInt();
String[] str = new String[n];
double s[] = new double[4];
double d[] = new double[4];
for(int i = 0;i < n;i++) {
str[i] = input.nextLine();
if(str[i].equals("rect")){
int width[] = new int[n];
width[i] = input.nextInt();
int length[] = new int[n];
length[i] = input.nextInt();
Rectangle[] sha = new Rectangle[i];
s[i] = sha[i].geta(width[i],length[i]);
d[i] = sha[i].getd(width[i],length[i]);
}
if(str[i].equals("cir")){
int[] circle = new int[n];
circle[i] = input.nextInt();
Circle[] sha = new Circle[i];
s[i] = sha[i].geta(circle[i]);
d[i] = sha[i].getd(circle[i]);
}
}
System.out.println(sumAllArea(s[0],s[1],s[2],s[3]));
System.out.println(sumAllPerimeter(d[0],d[1],d[2],d[3]));
}
public static double sumAllArea(double a,double b,double c,double d){
return a+b+c+d;
}
public static double sumAllPerimeter(double a,double b,double c,double d) {
return a+b+c+d;
}
}
abstract class shape{
static double PI = 3.14;
public shape() {
super();
// TODO Auto-generated constructor stub
}
}
class Circle extends shape{
int radius;
public Circle(int radius) {
this.radius = radius;
}
public double geta(int
题目集6(7-5、7-6)





部分代码如下
public Main() {
// TODO Auto-generated constructor stub
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int n = input.nextInt();
if(n!= 3&&n!=1&&n!=2&&n!=4) {
System.out.println("Wrong Format");
System.exit(n);
}
switch (n){
case 1:double str = input.nextDouble();
Circle s1 = new Circle(str);
if(str < 0) {
System.out.println("Wrong Format");
System.exit(n);
}
System.out.println("Circle's area:"+s1.getArea());
case 2:double st = input.nextDouble();
double s = input.nextDouble();
if(st<0||s<0) {
System.out.println("Wrong Format");
System.exit(n);
}
Rectangle s2 = new Rectangle(st,s);
System.out.println("Rectangle's area:"+s2.getArea());
case 3:double s33 = input.nextDouble();
if(s33 < 0) {
System.out.println("Wrong Format");
System.exit(n);
}
Ball s3 = new Ball(s33);
System.out.println("Ball's area:"+s3.getArea());
System.out.println("Ball's volume:"+s3.getVolume());
case 4:
double st1 = input.nextDouble();
double s11 = input.nextDouble();
double sh = input.nextDouble();
if(st1 < 0||s11<0||sh<0) {
System.out.println("Wrong Format");
System.exit(n);
}
Box s4 = new Box(st1,s11,sh);
System.out.println("Box's area:"+s4.getArea());
System.out.println("BOX's volume:"+s4.getVolume());
}
}
}
class shape{
static double PI = 3.14;
public shape() {
super();
// TODO Auto-generated constructor stub
System.out.println("Constructing shape");
}
public double getArea() {
return 0;
}
}
class Circle extends shape{
private double radius;
public Circle() {
System.out.println("Constructing radius");
}
public Circle(double c) {
super();
radius = c;
System.out.println("Constructing radius");
}
public void setRadius(int radius) {
this.radius = radius;
7-6
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
class gongjv implements Comparator<Double>{
@Override
public int compare(Double o1, Double o2) {
if(o1>o2) {
return 1;
}else if(o1<o2) {
return -1;
}else
return 0;
}
}
class Circle{
double 半径;
public boolean 是否合法() {
if(this.半径>0) {
return true;
}else {
return false;
}
}
public Circle(double 半径) {
super();
this.半径 = 半径;
}
public double 求面积(){
return Math.PI*半径*半径;
}
}
class Rectangle{
double 长,宽;
public boolean 是否合法() {
if(this.宽>0&this.长>0) {
return true;
}else {
return false;
}
}
public Rectangle(double 长, double 宽) {
super();
this.长 = 长;
this.宽 = 宽;
}
public double 求面积(){
return 宽*长;
}
}
class Triangle{
double a,b,c;
public Triangle(double a, double b, double c) {
super();
this.a = a;
this.b = b;
this.c = c;
}
public double 求面积(){
return Math.sqrt((a+b+c)*(a+b-c)*(a+c-b)*(b+c-a))/4;
}
public boolean 是否符合三边关系() {
double a[] = new double[3];
这三次的图形继承类题目,每次的难度都有所加大,第一次是经典的继承,然后要用到继承的特性覆盖,子方法将父类中的同名的方法覆盖,第二次图形继承,那题目则难度更进一步,而且更复杂一点,运用了多态这个方法,并且在子类的子类中又添加了新的方法,体现了程序的灵活性,第三次题目叫原先两次,虽然更为没有那么复杂,但要用接口做,接口的功能非常强大,使程序的灵活性更上升一层,很好的体现了继承和多态的思想
关于正则表达式的使用
如今很多语言都支持正则表达式, 它定义了一套自己的语法规则 (常见语法包括;字符匹配、重复匹配、字符定位、转义匹配和其他高级语法)来完成各种资料的验证, 功能之强大在我看来几乎到了无敌的地步. 但是据我所了解(呵呵, 很可能是坐井观天, 如果有让哪位不爽请原谅我没见过世面)很多很多自称为(或他称)程序员的在平时的工作中很少用到正则表达式, 不知道什么原因, 可能是熟悉的环境比较安稳, 懒得求新; 也可能是当看到一长串诸如: ^([/w-/.]+)@((/[[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}/.)|(([/w-]+/.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(/]?)$ 的外星符号时眼眨晕, 不想求新;当然也可能是基本掌握了一些常用的资料验证的正则表达式, 便不想再去了解其中的原理.
当然这种现象是好是坏不好评说, 每个人想的都会有所不同. 但我依然强烈建议学懂它, 掌握正则表达式的使用方法会给工作带来很多方便, 因为它除了对于资料验证游刃有余外, 还能查找和查找替换,能在文本和数据流里测试特定的条件。能从大量的邮件中剔除垃圾邮件。在垃圾邮的回收应用中,程序使用正则表达式来判断在来信栏内是否存在已知的垃圾邮件地址。
以下的几个例子
验证 E-mail格式
public bool IsEmail(string str_Email)
{
return System.Text.RegularExpressions.Regex.IsMatch(str_Email,
@"^([/w-/.]+)@((/[[0-9]{1,3}/.[0-9]{1,3}/.[0-9]{1,3}/.)|(([/w-]+/.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(/]?)$");
}
2. 验证 IP 地址
public bool IPChec(string IP)
{
string num = "(25[0-5]|2[0-4]//d|[0-1]//d{2}|[1-9]?//d)";
return Regex.IsMatch(IP, ("^" + num + "//." + num + "//." + num + "//." + num + "$"));
}
3. 验证 URL
public bool IsUrl(string str_ur)
{
return System.Text.RegularExpressions.Regex.IsMatch(str_ur, @"http(s)?://([/w-]+/.)+[/w-]+(/[/w- ./?%&=]*)?");
}
正则表达式的使用非常的方便,这是一定要学会的
题目集5(7-4)中Java集合框架应用的分析总结
代码如下
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
/*
abstract、assert、boolean、break、byte、case、catch、
char、class、const、continue、default、do、double、else、
enum、extends、false、final、finally、float、
for、goto、if、implements、import、instanceof、
int、interface、long、native、new、null、package、
private、protected、public、return、short、static、
strictfp、super、switch、synchronized、this、throw、
throws、transient、true、try、void、volatile、while
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input=new Scanner(System.in);
String a;
StringBuilder ss=new StringBuilder();
Map<String, Integer> map=new HashMap<String, Integer>();
String []key= { "abstract","assert","boolean","break","byte","case","catch",
"char","class","const","continue","default","do","double","else",
"enum","extends","false","final","finally","float",
"for","goto","if","implements","import","instanceof",
"int","interface","long","native","new","null","package",
"private","protected","public","return","short","static",
"strictfp","super","switch","synchronized","this","throw",
"throws","transient","true","try","void","volatile","while"
};
int j=0;
for(int i=0;;i++) {
a=input.nextLine();
if(a.equals("exit"))
break;
if(a.matches("(.*)//(.*)"))
{String b[]=a.split("//");
ss.append(b[0]+" ");
//ss.append('\n');
}
else
{ss.append(a+" ");
//ss.append('\n');
}
}
int count=0;
String s=ss.toString();
// System.out.println(s);
Pattern p=Pattern.compile("\"(.*?)\"");
Matcher m=p.matcher(s);
while(m.find()){
s=s.replace(m.group()," ");
p=Pattern.compile("\"(.*?)\"");
m=p.matcher(s);
}
p=Pattern.compile("/\\**(.*?)/");
m=p.matcher(s);
while(m.find()){
s=s.replace(m.group()," ");
// p=Pattern.compile("/\\*(.*?)\\*/");
m=p.matcher(s);
}
// System.out.println(s);
if(s.isEmpty())
{System.out.println("Wrong Format");
System.exit(0);
}
s=s.replace("["," ");
s=s.replace("]"," ");
s=s.replace("-","a");
s=s.replace("*","a");
s=s.replace("/","a");
s=s.replace("+","a");
s=s.replace(">","a");
s=s.replace("=","a");
s=s.replace("!","a");
s=s.replace(":","a");
s=s.replace("\\","a");
s= s.replaceAll("[^a-zA-Z]", " ");
String []s1=s.split("[ ' ']");
for(int i=0;i<s1.length;i++)
{//System.out.println(s1[i]);
for( j=0;j<key.length;j++)
if(s1[i].equals(key[j]))
{
map.put(key[j], 0);
}
}
for( int i = 0;i<s1.length;i++)
{
for( j=0;j<key.length;j++)
if(s1[i].equals(key[j]))
{ count=map.get(key[j]);
map.put(key[j], count+1);
}
}
Set set = map.keySet();
Object[] arr=set.toArray();
Arrays.sort(arr);
for(Object k:arr){
System.out.println(map.get(k)+"\t"+k);
}
}
}
这个题目的思路其实非常简单,就是要了解关于正则表达式有关方法的使用,将整个输入储存在一个链表中,用正则表达式matcher和replace等的方法,就能完成题目的求解,题目本身的结构非常简单,就是只有一个主函数,是一个典型的正则表达式的题目。
采坑心得:
我时常会在对象上出错,搞不清楚要对哪个对象下手,经常会把问题复杂化,而且喜欢重复使用写过的代码,导致一个题目代码就很长,不利于整体的美观性,还有我的代码有时容易出错,我的一个类中,有很多方法但是有些方法都是没用的,
改进建议:
我应该多注意一下单一职责原则和开闭性原则
浙公网安备 33010602011771号