下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

JAVA如何实现自动编号系统

作者:课课家教育     来源: http://www.kokojia.com点击数:998发布时间: 2016-03-07 11:13:43

标签: java自动编号java编辑java语言

大神带你学编程,欢迎选课

  功能需求:

  1,根据章节和当前标题数量,获得下一个编号,满足不同等级编号需求.如同word中的自动编号功能一样

  2,可以实现在freemarker中直接调用生成方法,得到正确的编号

  目标:即在freemarker代码中通过一个方法调用即可得到当前章节的编号

JAVA如何实现自动编号系统_java自动编号_java编辑_课课家

  1

  1.1

  1.2

  2

  2.1

  2.1.1

  2.1.2

  2.2

  2.2.1

  3

  3.1

  3.1.1

  3.1.1.1

  3.2

  思路:

  1,编号整体上是树形结构,因此要用树来管理整个列表

  2,有一个方法可以根据最大值,获取下一个(比如:最大值3,下一个4,最大值四,下一个五),这种增量方式是可以扩展和重新定义的.

  3,章节间的分隔符是可以指定的,在定义过程中应该指定.

  不多说,上代码:

  public abstract class Number {

  public abstract String produceNext(String crrnt);

  public String rootNumber() {

  return "0";

  }

  public String firstNumber() {

  return "1";

  }

  }

  编号抽象类,定义编号的元素类(如1,2,3或一,二,三)

  实现类:

  public class SerialNumber extends Number {

  @Override

  public String produceNext(String crrnt) {

  String next = "0";

  if (crrnt != null) {

  try {

  int crrntNum = Integer.parseInt(crrnt);

  next = String.valueOf(crrntNum + 1);

  } catch (Exception e) {

  System.err.println("非数字类型的字符串!");

  }

  }

  return next;

  }

  }

  节点类:

  public class Node implements Comparable {

  private String id;

  private String number;

  private String text;

  private String parentId;

  private int level;

  public Node(String id, String number, String parentId, int level) {

  this.id = id;

  this.number = number;

  this.parentId = parentId;

  this.level = level;

  }

  public Node() {

  }

  public String getId() {

  return id;

  }

  public void setId(String id) {

  this.id = id;

  }

  public String getNumber() {

  return number;

  }

  public void setNumber(String number) {

  this.number = number;

  }

  public String getText() {

  return text;

  }

  public void setText(String text) {

  this.text = text;

  }

  public String getParentId() {

  return parentId;

  }

  public void setParentId(String parentId) {

  this.parentId = parentId;

  }

  public int gETLevel() {

  return level;

  }

  public void setLevel(int level) {

  this.level = level;

  }

  @Override

  public int compareTo(Node o) {

  if (this.level != o.level) {

  return o.level - this.level;

  } else {

  if(this.number==null){

  return -1;

  }

  return this.number.compareTo(o.number);

  }

  }

  @Override

  public String toString() {

  return "id=" + this.id + " pId=" + this.parentId + " number=" + this.number + " text=" + this.text + "\\r\\n";

  }

  }

  具体操作过程:

  public class NumberTree {

  private String id;

  private List nodeList;

  private String separator;

  private int idSeq;

  private Number number;

  public NumberTree() {

  init();

  }

  public NumberTree(String separator, Number number) {

  init();

  this.separator = separator;

  this.number = number;

  }

  public void init() {

  idSeq = 0;

  this.separator = ".";

  if (this.nodeList == null) {

  nodeList = new ArrayList();

  }

  }

  public String getId() {

  return id;

  }

  public void setSerialId(String id) {

  this.id = id;

  }

  public String getSeparator() {

  return separator;

  }

  public void setSeparator(String separator) {

  this.separator = separator;

  }

  public List getNodeList() {

  return nodeList;

  }

  public void setNodeList(List nodeList) {

  this.nodeList = nodeList;

  }

  /**

  *

  *功能描述:根据父节点获取所有子节点。

  * @param pNode

  * @return

  * @since JDk1.6。

  *创建日期:2015-4-23 下午8:20:47。

  *更新日期:[日期YYYY-MM-DD][变更描述]。

  */

  public List getChildNodes(Node pNode) {

  String pId = pNode.getId();

  return getChildNodes(pId);

  }

  /**

  *

  *功能描述:根据父节点获取所有子节点。

  * @param pId

  * @return

  * @since JDK1.6。

  *创建日期:2015-4-23 下午8:21:02。

  *更新日期:[日期YYYY-MM-DD][变更描述]。

  */

  public List getChildNodes(String pId) {

  List childNodes = new ArrayList();

  for (Node n : nodeList) {

  if (pId.equals(n.getParentId())) {

  childNodes.add(n);

  }

  }

  return childNodes;

  }

  /**

  *

  *功能描述:本级最大节点的下一个。

  * @param level

  * @return

  * @since JDK1.6。

  *创建日期:2015-4-23 下午7:44:15。

  *更新日期:[日期YYYY-MM-DD][变更描述]。

  */

  public Node generateNextNodeForThisLevel(Node node) {

  Node nextNode = null;

  Node maxNode = getMaxNodeForThisLevel(node);

  String nextNumber = number.firstNumber();

  int level = node.getLevel();

  if (maxNode != null && !"0".equals(maxNode.getId())) {//本级存在子节点,且非根节点

  nextNumber = number.produceNext(maxNode.getNumber());

  level = maxNode.getLevel();

  }

  nextNode = new Node(String.valueOf(++idSeq), nextNumber, node.getId(), level);

  generateNodeText(nextNode, nextNumber);

  return nextNode;

  }

  /**

  *

  *功能描述:获取本级值最大的节点。

  * @param level

  * @return

  * @since JDK1.6。

  *创建日期:2015-4-23 下午7:43:26。

  *

  更新日期:[日期YYYY-MM-DD][变更描述]。

  */ public Node getMaxNodeForThisLevel(Node pNode) { List childList = getChildNodes(pNode); Node root = getRoot(nodeList); if (childList.size() <= 0) { return null; } int level = pNode.getLevel(); Node maxNode = root; for (Node node : childList) { if (maxNode.getNumber().compareTo(node.getNumber()) < 0) { maxNode = node; } } return maxNode; } /** * *

  功能描述:根据内容获取节点。

  * @param text * @return * @since JDK1.6。 *

  创建日期:2015-4-23 下午8:34:44。

  *

  更新日期:[日期YYYY-MM-DD][变更描述]。

  */ public Node getNodeByText(String text) { Node node = null; for (Node n : nodeList) { if (text.equals(n.getText())) { node = n; } } return node; } /** * *

  功能描述:生成下一个子节点。

  * @param node 父节点或兄弟节点 生成根节点时设为null * @return * @since JDK1.6。 *

  创建日期:2015-4-23 下午10:22:58。

  */ public Node generateNextChildNode(Node node) { Node newNode = generateNextNodeForThisLevel(node); return newNode; } /** * *

  功能描述:获取父节点。

  * @param node * @return * @since JDK1.6。 *

  创建日期:2015-4-23 下午8:44:50。

  */ public Node getParentNode(Node node) { for (Node n : nodeList) { if (node.getParentId() == n.getId()) { return n; } } return node; } /** * *

  功能描述:生成节点路径。

  * @param node * @return * @since JDK1.6。 *

  创建日期:2015-4-23 下午7:42:45。

  *

  更新日期:[日期YYYY-MM-DD][变更描述]。

  */ public void generateNodeText(Node node, String text) { if (node == null || "0".equals(node.getId())) { return; } Node pNode = getParentNode(node); if (!"0".equals(pNode.getId())) { text = pNode.getText() + separator + text; } node.setText(text); } /** * *

  功能描述:遍历所有树节点。

  * @param node * @since JDK1.6。 *

  创建日期:2015-4-24 上午9:39:13。

  *

  更新日期:[日期YYYY-MM-DD][变更描述]。

  */ public void traverseNodeList(Node node) { if(node==null){ node = getRoot(nodeList); } List childNodes = getChildNodes(node); System.out.println(node.getText()); if (childNodes.size() > 0) { for (Node n : childNodes) { traverseNodeList(n); } } } public static void main(String[] args) { Number number = new SerialNumber(); NumberTree treeNode = new NumberTree(".", number); addSomeNodes(treeNode); treeNode.traverseNodeList(null); } /** * *

  功能描述:获取根节点。

  * @param nodeList * @return * author zhangxl * @since JDK1.6。 *

  创建日期:2015-5-17 下午6:09:23。

  */ public Node getRoot(List nodeList) { Node root = null; if (nodeList.size() <= 0 || (root = getNodeById(nodeList, "0")) == null) { root = createRoot(); nodeList.add(root); } return root; } private Node getNodeById(List nodeList, String id) { Node node = null; if(id!=null){ for (Node n : nodeList) { if (id.equals(n.getId())) { node = n; break; } } } return node; } private Node createRoot() { Node root = new Node("0", number.rootNumber(), "-1", 0); root.setText("0"); return root; } /** * *

  功能描述:测试添加节点。

  * @return * @since JDK1.6。 *

  创建日期:2015-4-24 上午10:53:22。

  *

  更新日期:[日期YYYY-MM-DD][变更描述]。

  */ private static Node addSomeNodes(NumberTree tree) { Node root = tree.getRoot(tree.nodeList); Node node1 = getNextNode(tree, root);//1 Node node2 = getNextNode(tree, root);//2 Node node3 = getNextNode(tree, root);//3 Node node11 = getNextNode(tree, node1);//1.1 Node node12 = getNextNode(tree, node1);//1.2 Node node21 = getNextNode(tree, node2);//2.1 Node node211 = getNextNode(tree, node21);//2.1.1 Node node212 = getNextNode(tree, node21);//2.1.2 Node node22 = getNextNode(tree, node2);//2.2 Node node221 = getNextNode(tree, node22);//2.2.1 Node node31 = getNextNode(tree, node3); Node node32 = getNextNode(tree, node3); Node node311 = getNextNode(tree, node31); Node node3111 = getNextNode(tree, node311); return root; } public static Node getNextNode(NumberTree tree, Node pNode) { Node node = tree.generateNextChildNode(pNode); if (node != null) { tree.nodeList.add(node); } return node; } }

  getNextNode(NumberTree tree, Node pNode)

  该方法设计成静态方法,是为了在freemarker中调用方便.把NumberTree注册到freemarker中,就可以实现随意调用了.

  dataMap.put("numberTree", FtlUtil.getHelperClass("com.report.bctcms.number.NumberTree"));

  public class FtlUtil {

  public static TemplateHashModel useStaticPackage(String packageName) {

  TemplateHashModel fileStatics = null;

  try {

  BeansWrapper wrapper = BeansWrapper.getDefaultInstance();

  TemplateHashModel staticModels = wrapper.getStaticModels();

  fileStatics = (TemplateHashModel) staticModels.get(packageName);

  } catch (Exception e) {

  e.printStackTrace();

  }

  return fileStatics;

  }

  public static TemplateHashModel getHelperClass(String clazz) {

  TemplateHashModel useStaticPackage = FtlUtil.useStaticPackage(clazz);

  return useStaticPackage;

  }

  }

  freemarker代码:

  <#assign numberTree = root.numberTree />--注册的类

  <#assign numberTreeObj = root.numberTreeObj />--当前的操作对象

  <#assign rootNode = root.rootNode />--从进入freemarker开始的其实节点

  <#assign num1 = numberTree.getNextNode(numberTreeObj,rootNode)/>--生成的标题对象(Node)

  不足之处:

  1,暂时只支持生成子节点的编号,不支持兄弟节点编号

  2,生成一个编号对象需要的依赖比较多,稍显繁琐,但根据目前的需求只能如此

赞(24)
踩(0)
分享到:
华为认证网络工程师 HCIE直播课视频教程