这只是一篇我自己学习java的流水账笔记,包含了以下内容,全是基础代码示例,希望对正在学习java的小伙伴有帮助,现在小编就来说说关于java从入门到精通笔记?下面内容希望能帮助到你,我们来一起看看吧!
java从入门到精通笔记
这只是一篇我自己学习java的流水账笔记,包含了以下内容,全是基础代码示例,希望对正在学习java的小伙伴有帮助
- java基本算法:基本算法
- java设计模式:设计模式
package com.scriptwang.test1;
import java.util.Date;
/**
* Created by ScriptWang on 16/12/2.
* 基本算法
*/
public class Test1 {
public static void main(String[] args){
test1();
}
public static void print(Object o){
System.out.println(o);
}
/**
* 打印100以内的素数
* 素数:只能被1和自身整除的数,换句话说,
* 如果除开1和自身还有另外两个整数相乘可以得到这个数
* 那么这个数就不是素数
* 比如2,3,5是素数
* 而4不是素数
*/
public static void test1(){
long time = new Date().getTime();
for(int i=1;i<=100;i ){
if (isPrime(i)) print(i);
}
long time1 = new Date().getTime();
print("Used time : " (time1 - time) );
}
//判断该数是否是素数
public static boolean isPrime(int i){
if (i == 1) return false;//任何时候1都不是素数
if (i == 2) return true;//任何时候2都是素数
/**
* 最普遍的方法,一个数传进来,比如5,循环2,3,4(不包括1和自身)
* 如果找到能够除尽的整数,则返回false,说明该数不是素数
*/
for (int j=2;j<i;j ) {
if (i % j == 0){
return false;
}
}
return true;
}
}
package com.scriptwang.test1;
import java.util.Date;
/**
* Created by ScriptWang on 16/12/3.
* 打印九九乘法表
*/
public class Test2 {
public static void main(String[] args){
test1();
}
//两层循环嵌套
public static void test1(){
long time = new Date().getTime();
for (int i=1;i<=9;i ){
for (int j=1;j<=i;j ){
System.out.print(i "*" j "=" (i*j) " ");
}
System.out.println(" ");
}
System.out.println("used time : " (new Date().getTime() - time));
}
}
package com.scriptwang.test1;
import java.util.Date;
/**
* Created by ScriptWang on 16/12/3.
* 打印10000以内的回文数字
* 回文数字:一个数字如果正反都表示同一个数字的话
* 那么这个数字就是回文数字
* 比如12521,141,252等
*/
public class Test3 {
public static void main(String[] args){
test1();
test2();
}
//利用字符串反转,缺点:效率低
public static void test1(){
long time = new Date().getTime();
//1~9不是回文数字,不用参加循环
for (int i=10;i<=10000;i ){
String oldNum = String.valueOf(i);
//利用StringBuilder的reverse方法反转字符串
String newNum = new StringBuilder(oldNum).reverse().toString();
if (newNum.equals(oldNum)) System.out.print(i " ");
}
System.out.println();
System.out.println("used time:" (new Date().getTime() - time));
}
//用%将int中的每个数字提取出来,再重新组装成新的数字,优点:效率高
//经过测试,此法是字符串取反方法效率的两倍至三倍
public static void test2(){
long time = new Date().getTime();
for (int i=10;i<=10000;i ){
int value = i;//临时保存i的值
int oldNum = i;//保存i的值,用来和refNum比较
int temp1 = 0;//保存每次乘以10的结果
int temp2 = 0;//保存每次循环的个位数
int refNum = 0;//保存结果
/**
* 一个数去 % 10回得到这个数的最后一位(个位),比如123=3,546=6;
* 一个int去除以10会舍去小数点后面的数字,比如int num=123,num=num/10,此时的num为12
* 下面的算法正是利用了这两个特点,将一个数"倒装"起来.
*/
while (value > 0){
//将每次得到的结果乘10达到个位变十位,十位变百位... 的效果
temp1 = refNum * 10;
//将每次的value值,得到当前value值的最一位
temp2 = value % 10;
//得到每次处理后的结果
refNum = temp1 temp2;
//更新value,丢掉value的最后以为(因为value是int型的,会丢掉小数)
//当value只有一位数的时候,valu/10的结果为0推出循环
value /= 10;
}
if (refNum == oldNum) System.out.print(i " ");
}
System.out.println();
System.out.println("used time:" (new Date().getTime() - time));
}
}
/**
* Created by Script Wang on 2016/12/12.
*/
public class Sort {
public static void main(String[] args){
int[] s = new int[20];
for (int i=0;i<s.length;i ){
s[i] = (int)(Math.random()*100);
}
Sort.insertSort(s);
for (int i=0;i<s.length;i ) System.out.print(s[i] " ");
}
/**
* 选择排序:将第一个(最后一个)数字与之后(前)的所有数字一一比较,如果发现有
* 比第一个数字还要小(大)的,调换他们的位置;循环完第一次将最小(大)的数字放在
* 了第一个(最后一个)位置,如此一直循环到最后一个数字位置。
*
*/
public static void selectionSort(int[] nums){
//从开始循环到最后
for (int i=0,temp=0;i<nums.length;i ) for (int j=i 1;j<nums.length;j ){
if (nums[i]>nums[j]){
temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
//从最后循环到开始
for (int temp=0,i=nums.length-1;i>=0;i--) for (int j=i-1;j>=0;j--){
if (nums[j]>nums[i]){
temp = nums[j];
nums[j] = nums[i];
nums[i] = temp;
}
}
}
/**
* 冒泡排序:从第一个(最后一个数开始),依次比较相邻的两个数,如果左数大于后数,
* 则调换位置,这样外循环循环一次,就将最大的数选出来放在最右边。
*/
public static void bubbleSort(int[] nums){
//从开始循环到最后
for (int i=0,temp=0;i<nums.length;i ) for (int j=0;j<nums.length-1-i;j ){
if(nums[j] > nums[j 1]){
temp = nums[j];
nums[j] = nums[j 1];
nums[j 1] = temp;
}
}
//从最后循环到开始
for (int temp=0,i=nums.length-1;i>=0;i--) for (int j=nums.length-1;j>nums.length-1-i;j--){
if (nums[j-1] > nums[j]){
temp = nums[j-1];
nums[j-1] = nums[j];
nums[j] = temp;
}
}
}
/**
* 插入排序:从第二个数开始,依次插入右边的数,左边的所有数总是排好序的了
* 如果发现右边将要排序的数大于与之相邻的左边的第一个数,那么内循环break!
* 比如:1,2,3,4,6外循环循环到6,内循环从6开始循环到2,发现6比4大,则
* 内循环break!
*
*/
public static void insertSort(int[] nums){
//从开始循环到最后
for (int i=1,temp=0;i<nums.length;i ) for (int j=i;j>0;j--){
if (nums[j-1] > nums[j]){
temp = nums[j-1];
nums[j-1] = nums[j];
nums[j] = temp;
}else break;//特别注意break,插入排序是将一个数插入到已经排好序的序列中
//如果发现待排序数大于左边的第一个数,那么break
}
//从最后循环到开始
for (int temp=0,i=nums.length-1-1;i>=0;i--) for(int j=i;j<=nums.length-1-1;j ){
if (nums[j] > nums[j 1]){
temp = nums[j];
nums[j] = nums[j 1];
nums[j 1] = temp;
}else break;
}
}
}
package com.scriptwang.dp;
/**
* Created by ScriptWang on 16/12/13.
*
* 单例模式的特点
* 1:只能有一个实例
* 2:它必须自行创建自己(自行进行初始化)
* 3:必须向整个系统提供这个实例
*
* 它有两种实现模式:懒汉式和恶汉式
*/
public class UserClass {
public static void main(String[] args){
Singleton1 s = Singleton1.getInstance();
Singleton1 s1 = Singleton1.getInstance();
System.out.println(s == s1);
Singleton2 s3 = Singleton2.getInstance();
}
}
//懒汉式 需要的时候才创建,但是可能会线程不安全,需要同步方法
class Singleton1{
private static int type;
private static String name;
private static Singleton1 s;
private Singleton1(){}//私有构造方法,不允许别人new
static {//在类被加载的时候自行初始化变量
type = 1;
name = "S";
}
//懒汉式:当需要的时候才创建该类的实例
public synchronized static Singleton1 getInstance(){
if (s == null) s = new Singleton1();
return s;
}
}
//恶汉式 在类被加载的时候初始化,可能会引起资源浪费
class Singleton2{
private static int type;
private static String name;
private static Singleton2 s;
private Singleton2(){}//私有构造方法,不允许别人new
static {
type = 1;
name = "S";
//恶汉式,在加载该类的时候就创建了该类的实例,而不管需要不需要
s = new Singleton2();
}
public static Singleton2 getInstance(){
return s;
}
}
实现这样一个逻辑:不允许客户端类new产品类,不管客户端调用多少次getInstance方法,始终返回同一个产品。
//产品类
public class Car {
private static Car c;//使用静态变量,保证每次返回的都是同一辆Car
private Car(){}//构造器私有,不允许别人new
static {//static语句块会在该类被Load的时候执行一次,对变量进行初始化
c = new Car();
}
public static Car getInstance(){//自己控制自己产生的过程,相当于静态工厂方法
//cheak something here
return c;
}
public void drive(){
System.out.println("Car is running...");
}
}
//客户端类
public class Test {
public static void main(String[] args){
Car c = Car.getInstance();//通过Car提供的静态方法拿到Car的实例,此实例的产生过程由Car自己控制(比如检查权限等)
c.drive();
Car c1 = Car.getInstance();
c1.drive();
System.out.println(c == c1);//打印true,说明c和c1指向同一个对象,这就是所谓的单例模式!
}
}
单例模式的另一个例子:坦克大战项目中的PropertyManager类,从配置文件中读取属性的时候,不需要每读取一次就new一个java.util.Properties的对象,这样太浪费资源,故使用单例模式!
//测试类
public class Test {
public static void main(String[] args){
String name = PropertyManager.getProperty("name");
System.out.println(name);//打印testMessage,表明读取属性成功
Properties p1 = PropertyManager.getInstance();
Properties p2 = PropertyManager.getInstance();
System.out.println(p1 == p2);//打印true,表明无论PropertyManager被怎么调用,其内部只有一个java.util.Properties类的实例(这就是单列模式的应用)
}
}
//属性文件,名称:properties
name=testMesage
//PropertyManager类
import java.io.IOException;
import java.util.Properties;
public class PropertyManager {
//在此例中p是单例,无论PropertyManager被怎么调用,内存中只有一个p
private static Properties p = null;
static {//当类被加载的时候初始化p,且static语句块只执行一次
p = new Properties();
try {
p.load(PropertyManager.class.
getClassLoader().getResourceAsStream(“properties”));//加载名为properties的属性文件
} catch (IOException e) {
e.printStackTrace();
}
}
private PropertyManager(){}//不允许别人直接new本类的对象
public static String getProperty(String key){//通过p拿到其属性值
return p.getProperty(key);
}
public static Properties getInstance(){
return p;
}
}
package com.scriptwang.Test;
import java.util.HashSet;
import java.util.Set;
/**
* Created by ScriptWang on 16/11/26.
*
* 对象池的使用示例
*/
public class Dog {
//加载类的时候初始化一个Set对象池,static的
private static Set<Dog> dogPool = new HashSet<>();
private String name;
private int age;
//构造方法私有,不允许别人new对象,只允许自己new对象
private Dog(String name,int age){
this.name = name;
this.age = age;
}
/**
*
* @param name
* @param age
* @return Dog
* 工厂方法,在构造对象的时候,如果对象池里有,就返回已有的对象,不再new
* 如果没有,则将new的对象加入到对象池中,并将其返回
*/
public static Dog newInstance(String name,int age){
//循环对象池
for (Dog dog : dogPool){
//比较name和age,如果相同,则返回对象池里已有的对象
if (dog.getName().equals(name) && dog.getAge() == age){
return dog;
}
}
//如果对象池里没有该对象,则new出新对象加入对象池并返回
Dog dog = new Dog(name, age);
dogPool.add(dog);
return dog;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString(){
return "Dog : " name " : " age;
}
}
package com.scriptwang.dp;
/**
* Created by ScriptWang on 16/12/13.
* 简单工厂模式:
* 有一系列产品,他们都属于某一种产品(Cat,Dog都属于Animal)
* 创建一个工厂来管理他们,这个工厂称为简单工厂
*
* 扩展性:当新添加一种产品的时候,就要在工厂方法里新添加if...else语句
*/
public class UserClass1 {
public static void main(String[] args){
Animal cat = new AnimalFactory().createAnimal(0);
Animal Dog = new AnimalFactory().createAnimal(1);
}
}
class Animal{
//...
}
class Cat extends Animal{
//...
}
class Dog extends Animal{
//...
}
class AnimalFactory{
public static Animal createAnimal(int type){
if (type == 0) return new Cat();
else if (type == 1) return new Dog();
return null;
}
}
//抽象产品
public abstract class Car {
String name;
public abstract void drive();//抽象方法,其子类必须实现
public static void print(Object o){System.out.println(o);}
}
//具体产品Bmw和Benz
public class Bmw extends Car{
Bmw(){this.name = "bmw";}
public void drive(){ print(name " is running!");}
}
public class Benz extends Car {
Benz(){this.name = "Bezn";}
public void drive(){print(name " is running!");}
}
//简单工厂
public class CarFactory {
private static Car car = null;
private CarFactory(){}//private构造方法,禁止别人new对象
public static Car createCar(String CarName){//工厂静态生产方法
try{//利用反射机制,这样新增加一个产品类并不需要修改工厂类
car = (Car) Class.forName(CarName).newInstance();
}catch(Exception){
e.printStackTrace();
}
return car;
}
}
//客户端类
public class UserClass {
public static void main(String[] agrs){
String name = “Benz”;//相当于从配置文件读取的字符串
Car c = CarFactory.createCar(name);//根据字符串用工厂生产产品
c.drive();//使用产品
}
}
package com.scriptwang.dp;
/**
* Created by ScriptWang on 16/12/13.
* 抽象工厂模式:
* 有一系列产品,他们都属于某一种产品(Cat,Dog都继承自Animal)
* 有一系列工厂,他们都从一个工厂继承,和产品的继承关系类似.
* 每一个产品都由一个工厂负责,new的是什么工厂就生产什么产品
*
* 扩展性:当新添一种产品的时候,就要新添加一种与之相对应的工厂
*/
public class UserClass1 {
public static void main(String[] args){
//创建的是什么工厂就生产什么
AnimalFactory a1 = new CatFactory();
AnimalFactory a2 = new DogFactory();
Animal cat = a1.createAnimal();//生产了猫
Animal dog = a2.createAnimal();//生产了狗
}
}
class Animal{
//...
}
class Cat extends Animal{
//...
}
class Dog extends Animal{
//...
}
abstract class AnimalFactory{
public abstract Animal createAnimal();
}
class CatFactory extends AnimalFactory{
public Animal createAnimal(){
return new Cat();
}
}
class DogFactory extends AnimalFactory{
public Animal createAnimal(){
return new Dog();
}
}
package com.scriptwang.dp;
import java.util.HashSet;
/**
* Created by ScriptWang on 16/12/13.
* 观察者模式:当被观察者对象作出更改时,被观察者会主动通知观察者,让观察者响应这种更改
*
*/
public class UserClass {
public static void main(String[] args){
Product p = new Product("《字体设计》",102.8);
WebObserver web = new WebObserver();
MailObserver mail = new MailObserver();
web.Reg(p);
mail.Reg(p);
p.setPrice(100.0);
System.out.println("==split line=====after unReg Observer===");
mail.unReg(p);
p.setPrice(10.0);
}
}
/**
* 观察者类
*/
class Observer{
public void update(Product p){};
//注册自己(把Product的HashSet拿过来,再把自己装进去)
public void Reg(Product p){
p.getObservers().add(this);
}
//撤销自己(把Product的HashSet拿过来,再把自己移除)
public void unReg(Product p){
p.getObservers().remove(this);
}
}
class WebObserver extends Observer{
@Override
public void update(Product p) {
String name = p.getName();
double price = p.getPrice();
System.out.println("网页助手:" name "已经降到" price "了!请及时更新网页信息");
}
}
class MailObserver extends Observer{
@Override
public void update(Product p) {
String name = p.getName();
double price = p.getPrice();
System.out.println("邮箱助手:" name "已经降到" price "了!");
}
}
class Product{
private String name;
private double price;
//同HashSet装载观察者对象,HashSet不允许重复值,可避免重复装载
HashSet<Observer> observers;
Product(String name,double price){
this.name = name;
this.price = price;
//在Product被初始化的时候初始化HashSet
observers = new HashSet<Observer>();
}
/**
*
* @return
* 此方法用于观察者注册与取消注册
*/
public HashSet<Observer> getObservers(){
return observers;
}
/**
* 依次回调Observer的update方法,让Observer作出相应响应
*/
public void notifyObserver(){
if (observers != null){
for (Observer o : observers){
o.update(this);
}
}
}
public double getPrice() {
return price;
}
/**
*
* @param price
* 当价格变化时通知Observer
*/
public void setPrice(double price) {
this.price = price;
this.notifyObserver();//通知
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import java.util.LinkedList;
/**
* Created by Script Wang on 2016/12/14.
* 单向链表(线性链表)的实现
* 1:一般说的链表指的是单向链表,只能从一头到另一头,不能反过来
* 如果是可以从两个方向遍历的,称为双向链表
* 2:链表的关键点在于它对每个节点的next指针的操作,不论是插入,删除或修改操作
* 都是去某个或某些节点的next引用!
*
*/
public class UserClass {
public static void main(String[] args){
Mylist list = new Mylist();
for (int i=0;i<20;i ) list.add(i,new Integer(i));
System.out.println(list);
}
}
class Mylist{
/**
* 节点内部类
*/
class Node {
Object data;//(数据域)
Node next;//(指针域)
Node(Object data){
this.data = data;
next = null;
}
public Object get(){
return data;
}
public String toString(){
return data.toString();
}
}
Node head;//头节点,是判断链表是否为空,获取链表长度等方法实现的重要成员变量!
Mylist(){
head = null;
}
public void clear(){
head = null;
}
public boolean isEmpty(){
if (head == null) return true;
return false;
}
public int length(){
int sum = 0;
//每循环一次更新n,直到n=null停止循环
for (Node n = head;n != null;n=n.next) sum ;
return sum;
}
/**
* 拿到某个节点,实质上是循环多少次n=n.next语句
*/
public Node get(int pos){
if (pos < 0 || pos > length()) {
throw new RuntimeException("一共有" length() "个对象,你要找啥?");
}
Node n = head;
for (int i=0;i<pos;i ) n=n.next;
return n;
}
public void add(int pos,Object data){
if(pos < 0) throw new RuntimeException("你要往负方向插?只能往0和正方向插!");
else if (pos > length()) throw new RuntimeException("下标大于最后一个元素!");
Node n = new Node(data);
if (pos == 0 ){
/**
* 此处理解需要注意,并不是n.next=head;head=n;n和head就无限循环了
* 而是:
* new MyList时,head值初始化为null,换句话说head = null
* 现在n.next = head;是说n.next指向null,而不是head自身
* head = n;再令head指向n
* 因此,最终的结果(在链表里面只有一个元素的时候)
* 是head -->> n -->> null
* 而不是 head -->> n -->> head (无限循环,当获取length的时候怎么获取?)
*/
n.next = head;
head = n;
}else if (pos == length()){
get(length()-1).next = n;
}else {
/**
* 这里的顺序是很有讲究滴,必须
* First:先把当前位置的Node赋值给n.next引用
* Second:再把n赋值给当前位置的上一个的next引用
* 不能颠倒!!!!!
*/
n.next = get(pos);
get(pos-1).next = n;
}
}
public Object remove(int pos){
if(pos < 0) throw new RuntimeException("你要往负方向移除?");
else if (pos > length()) throw new RuntimeException("下标大于最后一个元素!");
if (pos == 0) {
Node n = get(0);
head = get(1);
return n.get();
} else if (pos == (length()-1)) {
Node n = get(length()-1);
get(pos-1).next = null;
return n.get();
} else {
Node n = get(pos);
get(pos-1).next = get(pos 1);
return n.get();
}
}
public String toString(){
StringBuilder sb = new StringBuilder();
for (Node n = head;n != null;n = n.next) {
if (get(length()-1) == n) {
sb.append(n.toString());
continue;
}
sb.append(n.toString() " , ");
}
return "[" sb.toString() "]";
}
}