深入理解Java遗传算法

关于遗传算法的详细原理以及具体的定义这里就不多介绍,想了解的可以自行百度,下面就简单介绍下自己对遗传算法的理解,本文对基因的编码采用二进制规则。

算法思想:
      遗传算法参照达尔文的进化论,认为物种都是向好的方向去发展(适者生存),因此可以认为到足够的代数之后,得到的最值可实际的最值很接近。

算法步骤:

  • 1)随机产生一个种群;
  • 2)计算种群的适应度、最好适应度、最差适应度、平均适应度等指标;
  • 3)验证种群代数是否达到自己设置的阈值,如果达到结束计算,否则继续下一步计算;
  • 4)采用转盘赌法选择可以产生下一代的父代,产生下一代种群(种群中个体数量不变);
  • 5)种群发生基因突变;
  • 6)重复2、3、4、5步。

算法实现-基因部分
1、种群个体(这里认为是染色体),在个体中,我们为这个个体添加两个属性,个体的基因和基因对应的适应度(函数值)。

public class Chromosome {
  private boolean[] gene;//基因序列
  private double score;//对应的函数得分
}

2、随机生成基因序列,基因的每一个位置是0还是1,这里采用完全随机的方式实现。

public Chromosome(int size) {
  if (size <= 0) {
    return;
  }
  initGeneSize(size);
  for (int i = 0; i < size; i++) {
    gene[i] = Math.random() >= 0.5;
  }
} 

private void initGeneSize(int size) {
  if (size <= 0) {
    return;
  }
  gene = new boolean[size];
}

3、把基因转化为对应的值,比如101对应的数字是5,这里采用位运算来实现。

public int getNum() {
  if (gene == null) {
    return 0;
  }
  int num = 0;
  for (boolean bool : gene) {
    num <<= 1;
    if (bool) {
      num += 1;
    }
  }
  return num;
}

4、基因发生变异,对于变异的位置这里完全采取随机的方式实现,变异原则是由1变为0,0变为1。

public void mutation(int num) {
  //允许变异
  int size = gene.length;
  for (int i = 0; i < num; i++) {
    //寻找变异位置
    int at = ((int) (Math.random() * size)) % size;
    //变异后的值
    boolean bool = !gene[at];
    gene[at] = bool;
  }
}

5、克隆基因,用于产生下一代,这一步就是将已存在的基因copy一份。

public static Chromosome clone(final Chromosome c) {
  if (c == null || c.gene == null) {
    return null;
  }
  Chromosome copy = new Chromosome();
  copy.initGeneSize(c.gene.length);
  for (int i = 0; i < c.gene.length; i++) {
    copy.gene[i] = c.gene[i];
  }
  return copy;
}

6、父母双方产生下一代,这里两个个体产生两个个体子代,具体哪段基因差生交叉,完全随机。

public static List<Chromosome> genetic(Chromosome p1, Chromosome p2) {
  if (p1 == null || p2 == null) { //染色体有一个为空,不产生下一代
    return null;
  }
  if (p1.gene == null || p2.gene == null) { //染色体有一个没有基因序列,不产生下一代
    return null;
  }
  if (p1.gene.length != p2.gene.length) { //染色体基因序列长度不同,不产生下一代
    return null;
  }
  Chromosome c1 = clone(p1);
  Chromosome c2 = clone(p2);
  //随机产生交叉互换位置
  int size = c1.gene.length;
  int a = ((int) (Math.random() * size)) % size;
  int b = ((int) (Math.random() * size)) % size;
  int min = a > b ? b : a;
  int max = a > b ? a : b;
  //对位置上的基因进行交叉互换
  for (int i = min; i <= max; i++) {
    boolean t = c1.gene[i];
    c1.gene[i] = c2.gene[i];
    c2.gene[i] = t;
  }
  List<Chromosome> list = new ArrayList<Chromosome>();
  list.add(c1);
  list.add(c2);
  return list;
}

算法实现-遗传算法
1、对于遗传算法,我们需要有对应的种群以及我们需要设置的一些常量:种群数量、基因长度、基因突变个数、基因突变率等,具体参照如下代码:

public abstract class GeneticAlgorithm {
  private List<Chromosome> population = new ArrayList<Chromosome>();//种群
  private int popSize = 100;//种群数量
  private int geneSize;//基因最大长度
  private int maxIterNum = 500;//最大迭代次数
  private double mutationRate = 0.01;//基因变异的概率
  private int maxMutationNum = 3;//最大变异步长 

  private int generation = 1;//当前遗传到第几代 

  private double bestScore;//最好得分
  private double worstScore;//最坏得分
  private double totalScore;//总得分
  private double averageScore;//平均得分 

  private double x; //记录历史种群中最好的X值
  private double y; //记录历史种群中最好的Y值
  private int geneI;//x y所在代数
}

2、初始化种群,在遗传算法开始时,我们需要初始化一个原始种群,这就是原始的第一代。

private void init() {
  for (int i = 0; i < popSize; i++) {
    population = new ArrayList<Chromosome>();
    Chromosome chro = new Chromosome(geneSize);
    population.add(chro);
  }
  caculteScore();
}

3、在初始种群存在后,我们需要计算种群的适应度以及最好适应度、最坏适应度和平均适应度等。

private void caculteScore() {
  setChromosomeScore(population.get(0));
  bestScore = population.get(0).getScore();
  worstScore = population.get(0).getScore();
  totalScore = 0;
  for (Chromosome chro : population) {
    setChromosomeScore(chro);
    if (chro.getScore() > bestScore) { //设置最好基因值
      bestScore = chro.getScore();
      if (y < bestScore) {
        x = changeX(chro);
        y = bestScore;
        geneI = generation;
      }
    }
    if (chro.getScore() < worstScore) { //设置最坏基因值
      worstScore = chro.getScore();
    }
    totalScore += chro.getScore();
  }
  averageScore = totalScore / popSize;
  //因为精度问题导致的平均值大于最好值,将平均值设置成最好值
  averageScore = averageScore > bestScore ? bestScore : averageScore;
}

4、在计算个体适应度的时候,我们需要根据基因计算对应的Y值,这里我们设置两个抽象方法,具体实现由类的实现去实现。

private void setChromosomeScore(Chromosome chro) {
  if (chro == null) {
    return;
  }
  double x = changeX(chro);
  double y = caculateY(x);
  chro.setScore(y); 

} 

/**
 * @param chro
 * @return
 * @Description: 将二进制转化为对应的X
 */
public abstract double changeX(Chromosome chro); 

/**
 * @param x
 * @return
 * @Description: 根据X计算Y值 Y=F(X)
 */
public abstract double caculateY(double x);

5、在计算完种群适应度之后,我们需要使用转盘赌法选取可以产生下一代的个体,这里有个条件就是只有个人的适应度不小于平均适应度才会长生下一代(适者生存)。

private Chromosome getParentChromosome (){
  double slice = Math.random() * totalScore;
  double sum = 0;
  for (Chromosome chro : population) {
    sum += chro.getScore();
    //转到对应的位置并且适应度不小于平均适应度
    if (sum > slice && chro.getScore() >= averageScore) {
      return chro;
    }
  }
  return null;
}

6、选择可以产生下一代的个体之后,就要交配产生下一代。

private void evolve() {
  List<Chromosome> childPopulation = new ArrayList<Chromosome>();
  //生成下一代种群
  while (childPopulation.size() < popSize) {
    Chromosome p1 = getParentChromosome();
    Chromosome p2 = getParentChromosome();
    List<Chromosome> children = Chromosome.genetic(p1, p2);
    if (children != null) {
      for (Chromosome chro : children) {
        childPopulation.add(chro);
      }
    }
  }
  //新种群替换旧种群
  List<Chromosome> t = population;
  population = childPopulation;
  t.clear();
  t = null;
  //基因突变
  mutation();
  //计算新种群的适应度
  caculteScore();
}

7、在产生下一代的过程中,可能会发生基因变异。

private void mutation() {
  for (Chromosome chro : population) {
    if (Math.random() < mutationRate) { //发生基因突变
      int mutationNum = (int) (Math.random() * maxMutationNum);
      chro.mutation(mutationNum);
    }
  }
}

8、将上述步骤一代一代的重复执行。

public void caculte() {
  //初始化种群
  generation = 1;
  init();
  while (generation < maxIterNum) {
    //种群遗传
    evolve();
    print();
    generation++;
  }
}

编写实现类

由于上述遗传算法的类是一个抽象类,因此我们需要针对特定的事例编写实现类,假设我们计算 Y=100-log(X)在[6,106]上的最值。

1、我们假设基因的长度为24(基因的长度由要求结果的有效长度确定),因此对应的二进制最大值为 1<< 24,我们做如下设置

public class GeneticAlgorithmTest extends GeneticAlgorithm{ 

  public static final int NUM = 1 << 24; 

  public GeneticAlgorithmTest() {
    super(24);
  }
}

2、对X值的抽象方法进行实现

@Override
public double changeX(Chromosome chro) {
  // TODO Auto-generated method stub
  return ((1.0 * chro.getNum() / NUM) * 100) + 6;
}

3、对Y的抽象方法进行实现

@Override
public double caculateY(double x) {
  // TODO Auto-generated method stub
  return 100 - Math.log(x);
}

运行结果

遗传算法思考
自己看了很多遗传算法的介绍,上面提到的最优解都是最后一代的最值,自己就有一个疑问了,为什么我知道前面所有带中的最值,也就是程序中的X  Y值,为什么不能用X Y值做遗传算法最后的结果值呢?

完整代码

1、Chromosome类

 /**
 *@Description: 基因遗传染色体
 */
package com.lulei.genetic.algorithm;  

import java.util.ArrayList;
import java.util.List; 

public class Chromosome {
  private boolean[] gene;//基因序列
  private double score;//对应的函数得分 

  public double getScore() {
    return score;
  } 

  public void setScore(double score) {
    this.score = score;
  } 

  /**
   * @param size
   * 随机生成基因序列
   */
  public Chromosome(int size) {
    if (size <= 0) {
      return;
    }
    initGeneSize(size);
    for (int i = 0; i < size; i++) {
      gene[i] = Math.random() >= 0.5;
    }
  } 

  /**
   * 生成一个新基因
   */
  public Chromosome() { 

  } 

  /**
   * @param c
   * @return
   * @Description: 克隆基因
   */
  public static Chromosome clone(final Chromosome c) {
    if (c == null || c.gene == null) {
      return null;
    }
    Chromosome copy = new Chromosome();
    copy.initGeneSize(c.gene.length);
    for (int i = 0; i < c.gene.length; i++) {
      copy.gene[i] = c.gene[i];
    }
    return copy;
  } 

  /**
   * @param size
   * @Description: 初始化基因长度
   */
  private void initGeneSize(int size) {
    if (size <= 0) {
      return;
    }
    gene = new boolean[size];
  } 

  /**
   * @param c1
   * @param c2
   * @Description: 遗传产生下一代
   */
  public static List<Chromosome> genetic(Chromosome p1, Chromosome p2) {
    if (p1 == null || p2 == null) { //染色体有一个为空,不产生下一代
      return null;
    }
    if (p1.gene == null || p2.gene == null) { //染色体有一个没有基因序列,不产生下一代
      return null;
    }
    if (p1.gene.length != p2.gene.length) { //染色体基因序列长度不同,不产生下一代
      return null;
    }
    Chromosome c1 = clone(p1);
    Chromosome c2 = clone(p2);
    //随机产生交叉互换位置
    int size = c1.gene.length;
    int a = ((int) (Math.random() * size)) % size;
    int b = ((int) (Math.random() * size)) % size;
    int min = a > b ? b : a;
    int max = a > b ? a : b;
    //对位置上的基因进行交叉互换
    for (int i = min; i <= max; i++) {
      boolean t = c1.gene[i];
      c1.gene[i] = c2.gene[i];
      c2.gene[i] = t;
    }
    List<Chromosome> list = new ArrayList<Chromosome>();
    list.add(c1);
    list.add(c2);
    return list;
  } 

  /**
   * @param num
   * @Description: 基因num个位置发生变异
   */
  public void mutation(int num) {
    //允许变异
    int size = gene.length;
    for (int i = 0; i < num; i++) {
      //寻找变异位置
      int at = ((int) (Math.random() * size)) % size;
      //变异后的值
      boolean bool = !gene[at];
      gene[at] = bool;
    }
  } 

  /**
   * @return
   * @Description: 将基因转化为对应的数字
   */
  public int getNum() {
    if (gene == null) {
      return 0;
    }
    int num = 0;
    for (boolean bool : gene) {
      num <<= 1;
      if (bool) {
        num += 1;
      }
    }
    return num;
  }
}

2、GeneticAlgorithm类

 /**
 *@Description:
 */
package com.lulei.genetic.algorithm;  

import java.util.ArrayList;
import java.util.List; 

public abstract class GeneticAlgorithm {
  private List<Chromosome> population = new ArrayList<Chromosome>();
  private int popSize = 100;//种群数量
  private int geneSize;//基因最大长度
  private int maxIterNum = 500;//最大迭代次数
  private double mutationRate = 0.01;//基因变异的概率
  private int maxMutationNum = 3;//最大变异步长 

  private int generation = 1;//当前遗传到第几代 

  private double bestScore;//最好得分
  private double worstScore;//最坏得分
  private double totalScore;//总得分
  private double averageScore;//平均得分 

  private double x; //记录历史种群中最好的X值
  private double y; //记录历史种群中最好的Y值
  private int geneI;//x y所在代数 

  public GeneticAlgorithm(int geneSize) {
    this.geneSize = geneSize;
  } 

  public void caculte() {
    //初始化种群
    generation = 1;
    init();
    while (generation < maxIterNum) {
      //种群遗传
      evolve();
      print();
      generation++;
    }
  } 

  /**
   * @Description: 输出结果
   */
  private void print() {
    System.out.println("--------------------------------");
    System.out.println("the generation is:" + generation);
    System.out.println("the best y is:" + bestScore);
    System.out.println("the worst fitness is:" + worstScore);
    System.out.println("the average fitness is:" + averageScore);
    System.out.println("the total fitness is:" + totalScore);
    System.out.println("geneI:" + geneI + "\tx:" + x + "\ty:" + y);
  } 

  /**
   * @Description: 初始化种群
   */
  private void init() {
    for (int i = 0; i < popSize; i++) {
      population = new ArrayList<Chromosome>();
      Chromosome chro = new Chromosome(geneSize);
      population.add(chro);
    }
    caculteScore();
  } 

  /**
   * @Author:lulei
   * @Description:种群进行遗传
   */
  private void evolve() {
    List<Chromosome> childPopulation = new ArrayList<Chromosome>();
    //生成下一代种群
    while (childPopulation.size() < popSize) {
      Chromosome p1 = getParentChromosome();
      Chromosome p2 = getParentChromosome();
      List<Chromosome> children = Chromosome.genetic(p1, p2);
      if (children != null) {
        for (Chromosome chro : children) {
          childPopulation.add(chro);
        }
      }
    }
    //新种群替换旧种群
    List<Chromosome> t = population;
    population = childPopulation;
    t.clear();
    t = null;
    //基因突变
    mutation();
    //计算新种群的适应度
    caculteScore();
  } 

  /**
   * @return
   * @Description: 轮盘赌法选择可以遗传下一代的染色体
   */
  private Chromosome getParentChromosome (){
    double slice = Math.random() * totalScore;
    double sum = 0;
    for (Chromosome chro : population) {
      sum += chro.getScore();
      if (sum > slice && chro.getScore() >= averageScore) {
        return chro;
      }
    }
    return null;
  } 

  /**
   * @Description: 计算种群适应度
   */
  private void caculteScore() {
    setChromosomeScore(population.get(0));
    bestScore = population.get(0).getScore();
    worstScore = population.get(0).getScore();
    totalScore = 0;
    for (Chromosome chro : population) {
      setChromosomeScore(chro);
      if (chro.getScore() > bestScore) { //设置最好基因值
        bestScore = chro.getScore();
        if (y < bestScore) {
          x = changeX(chro);
          y = bestScore;
          geneI = generation;
        }
      }
      if (chro.getScore() < worstScore) { //设置最坏基因值
        worstScore = chro.getScore();
      }
      totalScore += chro.getScore();
    }
    averageScore = totalScore / popSize;
    //因为精度问题导致的平均值大于最好值,将平均值设置成最好值
    averageScore = averageScore > bestScore ? bestScore : averageScore;
  } 

  /**
   * 基因突变
   */
  private void mutation() {
    for (Chromosome chro : population) {
      if (Math.random() < mutationRate) { //发生基因突变
        int mutationNum = (int) (Math.random() * maxMutationNum);
        chro.mutation(mutationNum);
      }
    }
  } 

  /**
   * @param chro
   * @Description: 设置染色体得分
   */
  private void setChromosomeScore(Chromosome chro) {
    if (chro == null) {
      return;
    }
    double x = changeX(chro);
    double y = caculateY(x);
    chro.setScore(y); 

  } 

  /**
   * @param chro
   * @return
   * @Description: 将二进制转化为对应的X
   */
  public abstract double changeX(Chromosome chro); 

  /**
   * @param x
   * @return
   * @Description: 根据X计算Y值 Y=F(X)
   */
  public abstract double caculateY(double x); 

  public void setPopulation(List<Chromosome> population) {
    this.population = population;
  } 

  public void setPopSize(int popSize) {
    this.popSize = popSize;
  } 

  public void setGeneSize(int geneSize) {
    this.geneSize = geneSize;
  } 

  public void setMaxIterNum(int maxIterNum) {
    this.maxIterNum = maxIterNum;
  } 

  public void setMutationRate(double mutationRate) {
    this.mutationRate = mutationRate;
  } 

  public void setMaxMutationNum(int maxMutationNum) {
    this.maxMutationNum = maxMutationNum;
  } 

  public double getBestScore() {
    return bestScore;
  } 

  public double getWorstScore() {
    return worstScore;
  } 

  public double getTotalScore() {
    return totalScore;
  } 

  public double getAverageScore() {
    return averageScore;
  } 

  public double getX() {
    return x;
  } 

  public double getY() {
    return y;
  }
}

3、GeneticAlgorithmTest类

 /**
 *@Description:
 */
package com.lulei.genetic.algorithm;  

public class GeneticAlgorithmTest extends GeneticAlgorithm{ 

  public static final int NUM = 1 << 24; 

  public GeneticAlgorithmTest() {
    super(24);
  } 

  @Override
  public double changeX(Chromosome chro) {
    // TODO Auto-generated method stub
    return ((1.0 * chro.getNum() / NUM) * 100) + 6;
  } 

  @Override
  public double caculateY(double x) {
    // TODO Auto-generated method stub
    return 100 - Math.log(x);
  } 

  public static void main(String[] args) {
    GeneticAlgorithmTest test = new GeneticAlgorithmTest();
    test.caculte();
  }
} 

以上就是关于Java遗传算法的详细介绍,希望对大家学习Java遗传算法有所帮助。

(0)

相关推荐

  • C++遗传算法类文件实例分析

    本文所述为C++实现的遗传算法的类文件实例.一般来说遗传算法可以解决许多问题,希望本文所述的C++遗传算法类文件,可帮助你解决更多问题,并且代码中为了便于读者更好的理解,而加入了丰富的注释内容,是新手学习遗传算法不可多得的参考代码. 具体代码如下所示: #include "stdafx.h" #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #inc

  • C++实现简单遗传算法

    本文实例讲述了C++实现简单遗传算法.分享给大家供大家参考.具体实现方法如下: //遗传算法 GA #include<iostream> #include <cstdlib> #include<bitset> using namespace std; const int L=5; //定义编码的长度 int f(int x) //定义测设函数f(x) { int result; result=x*x*x-60*x*x+900*x+100; return result;

  • java实现遗传算法实例分享(打印城市信息)

    复制代码 代码如下: import java.util.*;public class Tsp {      private String cityName[]={"北京","上海","天津","重庆","哈尔滨","长春","沈阳","呼和浩特","石家庄","太原","济南","

  • C++实现遗传算法

    本文实例讲述了C++实现简单遗传算法.分享给大家供大家参考.具体实现方法如下: // CMVSOGA.h : main header file for the CMVSOGA.cpp //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// #if !defined(AFX_CMV

  • 深入理解Java遗传算法

    关于遗传算法的详细原理以及具体的定义这里就不多介绍,想了解的可以自行百度,下面就简单介绍下自己对遗传算法的理解,本文对基因的编码采用二进制规则. 算法思想:       遗传算法参照达尔文的进化论,认为物种都是向好的方向去发展(适者生存),因此可以认为到足够的代数之后,得到的最值可实际的最值很接近. 算法步骤: 1)随机产生一个种群: 2)计算种群的适应度.最好适应度.最差适应度.平均适应度等指标: 3)验证种群代数是否达到自己设置的阈值,如果达到结束计算,否则继续下一步计算: 4)采用转盘赌法

  • Java遗传算法之冲出迷宫

    遗传算法是模拟达尔文生物进化论的自然选择和遗传学机理的生物进化过程的计算模型,是一种通过模拟自然进化过程搜索最优解的方法.它能解决很多问题,比如数学方程的最大最小值,背包问题,装箱问题等.在游戏开发中遗传算法的应用也十分频繁,不少的游戏 AI 都利用遗传算法进行编码. 就个人理解,遗传算法是模拟神奇的大自然中生物"优胜劣汰"原则指导下的进化过程,好的基因有更多的机会得到繁衍,这样一来,随着繁衍的进行,生物种群会朝着一个趋势收敛.而生物繁衍过程中的基因杂交和变异会给种群提供更好的基因序列

  • 深入理解java中的重载和覆盖

    说到java中的重载和覆盖呢,大家都很熟悉了吧,但是呢我今天就要写这个. 本文主题: 一.什么是重载 二.什么是覆盖 三.两者之间的区别 重载(overload): 在一个类中,如果出现了两个或者两个以上的同名函数,只要它们的参数的个数,或者参数的类型不同,即可称之为该函数重载了. 即当函数同名时,只看参数列表.和返回值类型没关系. 重载使用的时候需要注意: 1.在使用重载时只能通过不同的参数样式.例如,不同的参数类型,不同的参数个数,不同的参数顺序. 2.方法的异常类型和数目不会对重载造成影响

  • 深入理解Java class文件格式_动力节点Java学院整理

    Class文件在Java体系结构中的位置和作用 对于理解JVM和深入理解Java语言, 学习并了解class文件的格式都是必须要掌握的功课. 原因很简单, JVM不会理解我们写的Java源文件, 我们必须把Java源文件编译成class文件, 才能被JVM识别, 对于JVM而言, class文件相当于一个接口, 理解了这个接口, 能帮助我们更好的理解JVM的行为:另一方面, class文件以另一种方式重新描述了我们在源文件中要表达的意思, 理解class文件如何重新描述我们编写的源文件, 对于深

  • 深入理解Java中的final关键字_动力节点Java学院整理

    Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使用final关键字的实例.final经常和static一起使用来声明常量,你也会看到final是如何改善应用性能的. final关键字的含义? final在Java中是一个保留的关键字,可以声明成员变量.方法.类以及本地变量.一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如

  • 深入理解Java虚拟机_动力节点Java学院整理

    什么是Java虚拟机 Java程序必须在虚拟机上运行.那么虚拟机到底是什么呢?先看网上搜索到的比较靠谱的解释: 虚拟机是一种抽象化的计算机,通过在实际的计算机上仿真模拟各种计算机功能来实现的.Java虚拟机有自己完善的硬体架构,如处理器.堆栈.寄存器等,还具有相应的指令系统.JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行. 这种解释应该算是正确的,但是只描述了虚拟机的外部行为和功能,并没有针对内部原理

  • 深入理解Java 对象和类

    Java作为一种面向对象语言.支持以下基本概念: •多态 •继承 •封装 •抽象 •类 •对象 •实例 •方法 •消息解析 本节我们重点研究对象和类的概念. •对象:对象是类的一个实例,有状态和行为.例如,一条狗是一个对象,它的状态有:颜色.名字.品种:行为有:摇尾巴.叫.吃等. •类:类是一个模板,它描述一类对象的行为和状态. Java中的对象 现在让我们深入了解什么是对象.看看周围真实的世界,会发现身边有很多对象,车,狗,人等等.所有这些对象都有自己的状态和行为. 拿一条狗来举例,它的状态有

  • 深入理解Java中的接口

    一. 为什么要使用接口 假如有一个需求:要求实现防盗门的功能.门有"开"和"关"的功能,锁有"上锁"和"开锁"的功能. 分析:首先防盗门是一个门,门有开门和关门的功能,还有一把锁,锁有开锁和上锁,按照面向对象的编程的思想,我们会将门和锁都作为一个类而单独存在,但是,不能让防盗门继承自门的同时又继承自锁,防盗门不是锁,不符合继承中is a的关系,在java中支持单继承.那么我们如何来解决这一问题,这时就要用到接口. 二. 什么是

  • 快速理解Java垃圾回收和jvm中的stw

    Java中Stop-The-World机制简称STW,是在执行垃圾收集算法时,Java应用程序的其他所有线程都被挂起(除了垃圾收集帮助器之外).Java中一种全局暂停现象,全局停顿,所有Java代码停止,native代码可以执行,但不能与JVM交互:这些现象多半是由于gc引起. GC时的Stop the World(STW)是大家最大的敌人.但可能很多人还不清楚,除了GC,JVM下还会发生停顿现象. JVM里有一条特殊的线程--VM Threads,专门用来执行一些特殊的VM Operation

  • 深入理解java三种工厂模式

    适用场合: 7.3 工厂模式的适用场合 创建新对象最简单的办法是使用new关键字和具体类.只有在某些场合下,创建和维护对象工厂所带来的额外复杂性才是物有所值.本节概括了这些场合. 7.3.1 动态实现 如果需要像前面自行车的例子一样,创建一些用不同方式实现同一接口的对象,那么可以使用一个工厂方法或简单工厂对象来简化选择实现的过程.这种选择可以是明确进行的也可以是隐含的.前者如自行车那个例子,顾客可以选择需要的自行车型号:而下一节所讲的XHR工厂那个例子则属于后者,该例中所返回的连接对象的类型取决

随机推荐