龙空技术网

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

代码狂魔 116

前言:

眼前大家对“java 判断一个数是不是质数”大概比较着重,我们都想要学习一些“java 判断一个数是不是质数”的相关内容。那么小编在网上收集了一些对于“java 判断一个数是不是质数””的相关知识,希望小伙伴们能喜欢,同学们快快来学习一下吧!

这只是一篇我自己学习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类的实例(这就是单列模式的应用)    }}  //属性文件,名称:propertiesname=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和Benzpublic 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()+"]";    } }

标签: #java 判断一个数是不是质数