这只是一篇我自己学习java的流水账笔记,包含了以下内容,全是基础代码示例,希望对正在学习java的小伙伴有帮助
- java基本算法:基本算法
- java设计模式:设计模式
基本算法
打印100以内的素数
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)); } }
打印10000以内的回文数字
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%10=3,546%10=6; * 一个int去除以10会舍去小数点后面的数字,比如int num=123,num=num/10,此时的num为12 * 下面的算法正是利用了这两个特点,将一个数"倒装"起来. */ while (value > 0){ //将每次得到的结果乘10达到个位变十位,十位变百位... 的效果 temp1 = refNum * 10; //将每次的value值%10,得到当前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; } } }
设计模式
单例模式(Singleton)、多例模式(Multiton)
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; } }
简单工厂模式(Simple Factory)
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; } }
数据结构:java链表
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()+"]"; } }
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://sigusoft.com/bj/4707.html