长文慎点,Java学习笔记(六)

长文慎点,Java学习笔记(六)这只是一篇我自己学习 java 的流水账笔记 包含了以下内容 全是基础代码示例 希望对正在学习 java 的小伙伴有帮助 java 基本算法 基本算法 java 设计模式 设计模式基本算法打印 100 以内的素数 package com scriptwang t

这只是一篇我自己学习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()+"]";   } }
编程小号
上一篇 2024-12-07 17:28
下一篇 2024-12-07 17:24

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://sigusoft.com/bj/4707.html