重拾java系列一java基础(2)
1.分支流程控制
if(布尔表达式/分支条件){
//语句块
}
if(布尔表达式/分支条件){
//语句块1
}else{
//语句块2
}
if(条件1){
//语句块1
}else if(条件2){
//语句块2
}else if(条件3){
//语句块3
}
1) 尽量使用肯定条件,可以减少逻辑思考错误
2) 减少使用else
3) 减少嵌套层次,一般不要超过2层
4) 语句块不要超过一个屏幕!
5) 严格遵守缩进规则!
switch(整数条件){
case 常量: (break;)
case 常量:
default:
}
2.循环流程控制
for while do...while
1)for 经典用法: 与次数,连续变化的数列有关的循环
for(初始化;循环条件;递增){
循环体
}
2)for可以替代任何循环
2.1) 死循环
for(;;){
}
for(;true;){
}
2.2)
for(;循环条件;){
}
for while do...while 比较
1) for 常用,“经典使用方式”与固定次数有关循环处理
22) for 可以替代其它两种循环
2.1) for(;循环条件;){} 替代 while(循环条件){}
2.2) 死循环 for(;;){} 替代 while(true){}
2.3) for(;;){ if(循环条件) break; } 替代
do...while(循环条件);
3) while 循环用于在循环体开始时候判断循环条件
4) do ... while 循环用于在循环体结束时候判断循环条件
5) 在其他情况下使用 死循环!在适当的条件时候使用break
穿插小demo:
/**
*
* 案例:判断一个数是否是“水仙花数”
* 水仙花数:3位自幂数,是一个3位并且各个数字的3次方的和
* 与这个数相等
* 153 = 1*1*1 + 5*5*5 + 3*3*3
* = 1 + 125 + 27
* = 153
*/
public class Daffodil {
public static void main(String[] args) {
for(int n=100; n<=999; n++){
//int n = 153;// n = 100 101 ... 999
int num = n;
int sum = 0;
while(num!=0){
int last = num%10;
sum += last * last * last;
num /= 10;
}
if(sum == n){
System.out.println(n+"是水仙花数!");
}
}
}
}
斐波那契数列:
/**
* 菲波纳且
* 数列
* 1 1 2 3 5 8 13 21 ...
* 列数:1 2 3 4 5 6 7 8 ...
*
* f(n)/f(n+1) = 0.618
*
* 计算 第n项
* 1) 功能:计算菲波纳切数列的n项
* 2) 功能实现: n项 是 前两项的和 推理 从第一项加到n项
* 功能分析:
* 1 1 2 3 5 8 13 21 ...
* 1 2 3 4 5 6 7 8 ...
* n
* f1+f2=fn
* f1+f2=fn
*/
public class Demo02 {
public static void main(String[] args) {
System.out.println(f(8));
System.out.println((double)f(50)/f(51));
}
public static long f(int n){
long f1 = 1;long f2 = 1;long fn = 1;
for(int i=3; i<=n; i++){
fn = f1+f2; f1 = f2; f2 = fn;
}
return fn;
}
}
递归算法:
public static long f1(long n) {
if (n == 1 || n == 2) {
return 1;
}
return f1(n - 1) + f1(n - 2);
}
3.Arrays工具类(专门针对数组的工具类,未特殊说明,参数均为数组):
(1)Arrays.toString(Object[] a) 将数组的元素连接为一个字符串.
public static void main(String[] args) {
String[] names = { "susu", "Andy", "John", "Jerry" };
System.out.println(Arrays.toString(names));
//运行结果:[susu, Andy, John, Jerry]
}
下面让我们看一下为什么运行结果是上面的字符串?我们看一下Arrays.toString() API
public static String toString(Object[] a) {
if (a == null)
return "null";
int iMax = a.length - 1;
if (iMax == -1)
return "[]";
StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0;; i++) {
b.append(String.valueOf(a[i]));
if (i == iMax)
return b.append(']').toString();
b.append(", ");
}
}
一目了然,这便是底层代码的java实现,此时不如我们再扩展一下,直接输出System.out.println(names);发现返回的是[Ljava.lang.String;@3fbefab0咋一看这是什么玩意,由于任何类都是Object类的子类(后面部分会讲解到),而Object中定义的toString()方法api 如下:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
由此我们可以看到,Object类的toString()方法返回的是类名+hashcode值 (hashcode后面再讲),所以如果想要返回自定义的格式,就要像Arrays类一样,,重写(后面讲)Object的toString()即可。
(2)Arrays.equals(obj1,obj2) ,此方法用来比较两个数组是否相等,底层api很简单,如下:
public static boolean equals(char[] a, char[] a2) {
if (a==a2)
return true;
if (a==null || a2==null)
return false;
int length = a.length;
if (a2.length != length)
return false;
for (int i=0; i<length; i++)
if (a[i] != a2[i])
return false;
return true;
}
(3)Arrays.sort(names);//顾名思义,排序,我们先来看一下例子效果:
public static void main(String[] args) {
int[] a = {101,3,88,76,34,22};
String[] names = {"Tom","Andy","John","Jerry"};
Arrays.sort(names);
Arrays.sort(a);
System.out.println(Arrays.toString(names));
System.out.println(Arrays.toString(a));
//运行结果:[Andy, Jerry, John, Tom] [3, 22, 34, 76, 88, 101]
}
我们再来看一下底层api到底发生了什么:
/**
*
* @param a the array to be sorted
* @throws ClassCastException if the array contains elements that are not
* <i>mutually comparable</i> (for example, strings and integers).
*/
public static void sort(Object[] a) {
Object[] aux = (Object[]) a.clone();// 首先调用了clone()方法,以后会有专题来讲解clone()方法
//下面排序中主要针对克隆后的数组进行排序,排好序后再copy回待排序的数组,destnation
mergeSort(aux, a, 0, a.length, 0);// 调用归并排序方法
}
/**
* Tuning parameter: list size at or below which insertion sort will be used
* in preference to mergesort or quicksort.
* 调优参数:列表大小达到或者低于插入排序将优先使用归并排序和快速排序。
*/
private static final int INSERTIONSORT_THRESHOLD = 7;
/**
* Src is the source array that starts at index 0 //克隆后的数组
* Dest is the (possibly larger) array destination with a possible offset //待排序的数组
* low is the index in dest to start sorting //待排序的数组中开始排序的的起始索引,从0开始 ,排序时会发生变化
* high is the end index in dest to end sorting //待排序的数组的的截止索引,排序时会发生变化
* off is the offset to generate corresponding low, high in src//偏移量,位移
*/
private static void mergeSort(Object[] src, Object[] dest, int low,
int high, int off) {
int length = high - low;//待排序的数组长度
// Insertion sort on smallest arrays
// 数组长度比较小时使用插入排序,java底层的优化,设置插入排序的阀值为7,此时直接对待排序的数组进行排序
if (length < INSERTIONSORT_THRESHOLD) {
for (int i = low; i < high; i++)
for (int j = i; j > low
&& ((Comparable) dest[j - 1]).compareTo(dest[j]) > 0; j--)
//dest[j-1]至少从dest[0]开始,即起始元素开始,和下一个作比较,按照字典顺序,自然顺序,具体规则后面重点剖析,不等于0时,交换两者位置
swap(dest, j, j - 1);//交换位置
return;
}
// Recursively sort halves of dest into src
//递归排序
int destLow = low;
int destHigh = high;
low += off;
high += off;
int mid = (low + high) >>> 1;
mergeSort(dest, src, low, mid, -off);
mergeSort(dest, src, mid, high, -off);
// If list is already sorted, just copy from src to dest. This is an
// optimization that results in faster sorts for nearly ordered lists.
//如果列表已经被排好序,只需从src复制到dest,这是种优化的选择,结果是使用快速排序
if (((Comparable) src[mid - 1]).compareTo(src[mid]) <= 0) {
System.arraycopy(src, low, dest, destLow, length);
return;
}
// Merge sorted halves (now in src) into dest
// 归并
for (int i = destLow, p = low, q = mid; i < destHigh; i++) {
if (q >= high || p < mid
&& ((Comparable) src[p]).compareTo(src[q]) <= 0)
dest[i] = src[p++];
else
dest[i] = src[q++];
}
}
/**
* Swaps x[a] with x[b].//交换数组x中a,b对应位置的两个元素
*/
private static void swap(Object[] x, int a, int b) {
Object t = x[a];
x[a] = x[b];
x[b] = t;
}
由此可见,实际上java只不过封装了对应的排序方法,我们调用即可,关于以上里面的算法,我会单独拿出篇幅来分析
(4)Arrays.binarySeacher(Object[]a , obj1)//利用二分查找方法找出给定元素在给定数组中首次出现的位置,从0开始
public static void main(String[] args) {
String[] names = {"bss", "Tom", "Andy", "Jerry",
"John","yuuuuy", "Wang"};
int index;
index = Arrays.binarySearch(names, "Jerry");
System.out.println(index);
index = Arrays.binarySearch(names, "Tom");
System.out.println(index);//负数
// //以上的查找结果不确定!
Arrays.sort(names);
index = binarySearch(names, "John");
System.out.println(index);//2
//以上查找是稳定的结果
}
同样我们通过api分析:
public static int binarySearch(Object[] a, Object key) {
return binarySearch0(a, 0, a.length, key);
}
private static int binarySearch0(Object[] a, int fromIndex, int toIndex,
Object key) {
//初始化低位和高位索引
int low = fromIndex;//带查找范围的最低索引,可变
int high = toIndex - 1;//带查找范围的最高索引,可变
while (low <= high) {
int mid = (low + high) >>> 1;// 无符号右移,前面补0,后面舍去,先把数组分成两个阵营,
//先比较中间元素是否为所找元素,若是,则返回中对应index,
//若不是,则根据中间元素与待查元素的字典顺序判断是在前面查找还是后面查找了,以此类推
Comparable midVal = (Comparable) a[mid];// 之所以可以强转成Comparable,是因为该类(字符串)实现了Comparable接口,
int cmp = midVal.compareTo(key);
if (cmp < 0)// 按字典顺序,midVal比key排在前面,则返回负数
low = mid + 1;//从中间mid位置开始往后寻找目标,相当于新的起始位置,即新的low到最后中查找
else if (cmp > 0)// 按字典顺序,midVal排在key后面,则返回正数
high = mid - 1;//从中间mid位置开始往前寻找目标,相当于新的终止位置,即在0~新的high中查找
else
return mid; // key found
}
return -(low + 1); // key not found.
}
可以看出二分查找的方法,但要注意以下几点:
1) 在未排序的数组上使用二分查找结果不稳定.
2) 必须在排序的数组上使用二分查找!
3) 二分查找结果是元素的位置, 如果返回负数表示没有找到
(5)关于数组的复制:
public static void main(String[] args) {
int[] ary1 = {5,6,7};
int[] ary2 = ary1;
System.out.println(ary1==ary2);// true
System.out.println(Arrays.equals(ary1, ary2));// true
ary1[0] = 10;//对其中一个修改
ary1[1] = 20;//对另一个修改
System.out.println(Arrays.toString(ary1));//[10, 20, 7]
System.out.println(Arrays.toString(ary2));//[10, 20, 7]
//出现以上的结果是两者数组变量共同引用同一个对象
//复制数组 复制ary1引用的数组,比较笨拙的方法
int[] ary3 = new int[ary1.length];
for(int i=0; i<ary1.length; i++){
ary3[i] = ary1[i];
}
//Java 提供了复制数组的API, 可以简化复制,提高性能
int[] ary4 = new int[ary1.length];
// 源, 源位置,目标,目标位置, 数量
System.arraycopy(ary1, 0, ary4, 0, ary1.length);
System.out.println(Arrays.toString(ary4));
System.out.println(ary4==ary1);//false
System.out.println(ary4.equals(ary1));//false
//Arrays.copyOf() 方法更加便捷的复制数组, since Java 6
//底层调用的还是System.arraycopy()
int[] ary5 = Arrays.copyOf(ary1, ary1.length);
System.out.println(Arrays.toString(ary5));
System.out.println(ary1.equals(ary5));//false
}
而代码中最后的输出为false,是因为Arrays.copyOf()方法也是新new 了一个数组,参看api:
public static int[] copyOf(int[] original, int newLength) {
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
7 return copy;
}
重拾java系列一java基础(2)的更多相关文章
- 重拾java系列一java基础(1)
前言,不知不觉,从接触java到工作至今已有两年的时间,突然感觉自己的基础知识还很薄弱,有些知识虽然知道,但是停留在表面上,没有深挖,或者实践过,感觉掌握的很肤浅,而且时间一长,就觉得忘记了,我觉得这 ...
- 【java系列】java开发环境搭建
描述 本篇文章主要讲解基于windows 10系统搭建java开发环境,主要内容包括如下: (1)安装资料准备 (2)安装过程讲解 (3)测试是否安装成功 (4)Hello Word测试 1 安装 ...
- 重拾java系列一java基础(3)
这一章主要复习下以前所接触的算法, (1)选择排序法:在要排序的一组数中,选出最小的一个数与第一个位置的数交换:然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较 ...
- 重拾java系列一java基础(4)
本章主要回顾一些类的相关知识: (1)static: static 静态的: 属于类的资源, 使用类名访问. 静态属性: 只有一份的变量 静态方法: 是属于类方法, 可以使用类名直接访问. 静态方 ...
- java系列(1/4)基础阶段-MySQL(2/13)
本单元目标 一.为什么要学习数据库 二.数据库的相关概念 DBMS.DB.SQL 三.数据库存储数据的特点 四.初始MySQL MySQL产品的介绍 MySQL产品的安装 ★ MySQL服务的启动和停 ...
- Java系列: JAVA字符串格式化-String.format()的使用(zz)
常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重 ...
- 重拾Java Web应用的基础体系结构
目录 一.背景 二.Web应用 2.1 HTML 2.2 HTTP 2.3 URL 2.4 Servlet 2.4.1 编写第一个Servlet程序 2.5 JSP 2.6 容器 2.7 URL映射到 ...
- 夯实Java基础系列5:Java文件和Java包结构
目录 Java中的包概念 包的作用 package 的目录结构 设置 CLASSPATH 系统变量 常用jar包 java软件包的类型 dt.jar rt.jar *.java文件的奥秘 *.Java ...
- 【Java】 重拾Java入门
[概论与基本语法] 取这个标题,还是感觉有些大言不惭.之前大三的时候自学过一些基本的java知识,大概到了能独立写一个GUI出来的水平把,不过后来随着有了其他目标,就把这块放下了.之后常年没有用,早就 ...
随机推荐
- 【bzoj1038】瞭望塔
[bzoj1038]瞭望塔 题意 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折 ...
- 浅析KMP算法
浅析KMP算法 KMP算法是一种线性字符串的匹配算法,将主串S与模式串T匹配. 首先朴素算法大家都会,就是直接从S的每一个位置开始,枚举比较,时间效率为O(nm),现在要想到一种化简的方式,使得时间复 ...
- 三张图彻底了解Java中字符串的不变性
转载: 三张图彻底了解Java中字符串的不变性 定义一个字符串 String s = "abcd"; s中保存了string对象的引用.下面的箭头可以理解为"存储他的引用 ...
- 2014---多校训练一(A Couple doubi)
Couple doubi Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tota ...
- iOS 推送全解析
本文旨在对 iOS 推送(以下简称 推送)进行一个完整的剖析,如果你之前对推送一无所知,那么在你认真地阅读了全文后必将变成一个推送老手,你将会对其中的各种细节和原理有充分的理解.以下是 pikacod ...
- Java 集合系列 16 HashSet
java 集合系列目录: Java 集合系列 01 总体框架 Java 集合系列 02 Collection架构 Java 集合系列 03 ArrayList详细介绍(源码解析)和使用示例 Java ...
- javamail 学习及实例
JavaMail,是Sun发布的用来处理email的API,提供给开发者处理电子邮件相关的编程接口.通过使用它可以方便地执行一些常用的邮件传输. 可以看下<java邮件开发详解>第四章和第 ...
- MVC中view页面用jquery方法绑定select控件值
var sortid = '@Model.myWorkMatter.WorkMatterSortID'; $("#selectSort").val(sortid); $(" ...
- C++中颜色的设置
1.改变整个控制台的颜色用 system("color 0A"); 其中color后面的0是背景色代号,A是前景色代号.各颜色代码如下: 0=黑色 1=蓝色 2=绿色 3=湖蓝色 ...
- nssm在windows服务器上部署nodejs,coffee启动方式
本想用forever / pm2 来部署nodejs, 百度后发现只能在Linux系统上使用,window上没法使用,兜一圈后又转nssm了.... 在Linux上,可以轻松的使用forever或者p ...