掲示板などのコメントをツリー形式で表示する方法についてのメモ。
各レコードがidを持ち、子供は親のidをparentIdとして持っているものとします。たとえば、こんな感じのPersonクラスを想定します。
getChildrenは、「子のリストを作るメソッド」です。この中でそれぞれの子について、「子のリストを作るメソッド」を呼び出します。つまり、自分で自分を呼び出すわけです。このような呼び出し方を「再帰呼び出し」といいます。無限ループになりそうでちょっと恐いですね。コードはこんな感じです。
2つ目のfor文では、ツリー構造を分かりやすく示すために罫線を使っています。
まず、leaderを表示します(最初の階層では何も表示しません)。
自分の下にも兄弟がいれば名前の前に「┣」を表示し、自分の名前を表示してからleaderに「┃」を追加し、getChildrenを呼び出します。
自分の下に兄弟がいなければ「┗」を表示し、自分の名前を表示してからleaderに全角スペースを追加してgetChildrenを呼び出します。
上のコードを実行すると、表示は次のようになります。
各レコードがidを持ち、子供は親のidをparentIdとして持っているものとします。たとえば、こんな感じのPersonクラスを想定します。
class Person{
//フィールド
int _id;
int _parentId;
String _name;
//コンストラクタ
Person(int id,int parentId,String name){
_id=id;
_parentId=parentId;
_name = name;
}
}
Personクラスのコンストラクタでは、最初の引数がid、2番目の引数がparentId、3番目の引数が名前です。親を持たない場合はparentIdに0をセットします。ArrayListを用意して、次のような感じのデータを入れ、最後にgetChildrenを呼びます。//フィールド
int _id;
int _parentId;
String _name;
//コンストラクタ
Person(int id,int parentId,String name){
_id=id;
_parentId=parentId;
_name = name;
}
}
public class DispTree{
static ArrayList<Person> alPerson = new ArrayList<Person>();
public static void main(String[] args){
alPerson.add(new Person(1,0,"ナミヘイ"));
alPerson.add(new Person(2,1,"サザエ"));
alPerson.add(new Person(3,1,"カツオ"));
alPerson.add(new Person(4,1,"ワカメ"));
alPerson.add(new Person(5,2,"タラ"));
alPerson.add(new Person(6,4,"ヒラメ"));
alPerson.add(new Person(7,5,"タラコ"));
alPerson.add(new Person(8,2,"ブリ"));
alPerson.add(new Person(9,8,"ハマチ"));
alPerson.add(new Person(10,9,"イナダ"));
alPerson.add(new Person(11,8,"カンパチ"));
getChildren("",0);
}
上の例では、ナミヘイに親はなく、サザエ、カツオ、ワカメの親がナミヘイでタラ、ブリの親がサザエで、タラコの親がタラで、ハマチ、カンパチの親がブリで、イナダの親がハマチで、ヒラメの親がワカメです。static ArrayList<Person> alPerson = new ArrayList<Person>();
public static void main(String[] args){
alPerson.add(new Person(1,0,"ナミヘイ"));
alPerson.add(new Person(2,1,"サザエ"));
alPerson.add(new Person(3,1,"カツオ"));
alPerson.add(new Person(4,1,"ワカメ"));
alPerson.add(new Person(5,2,"タラ"));
alPerson.add(new Person(6,4,"ヒラメ"));
alPerson.add(new Person(7,5,"タラコ"));
alPerson.add(new Person(8,2,"ブリ"));
alPerson.add(new Person(9,8,"ハマチ"));
alPerson.add(new Person(10,9,"イナダ"));
alPerson.add(new Person(11,8,"カンパチ"));
getChildren("",0);
}
getChildrenは、「子のリストを作るメソッド」です。この中でそれぞれの子について、「子のリストを作るメソッド」を呼び出します。つまり、自分で自分を呼び出すわけです。このような呼び出し方を「再帰呼び出し」といいます。無限ループになりそうでちょっと恐いですね。コードはこんな感じです。
static void getChildren(String leader,int parentId){
ArrayList<Person> alChildren = new ArrayList<Person>();
for(Person person:alPerson){
if(person._parentId==parentId){
alChildren.add(person);
}
}
int intCount=0;
for(Person person:alChildren){
intCount++;
System.out.print(leader);
if(intCount<alChildren.size()){
System.out.print("┣");
System.out.println(person._name);
getChildren(leader+"┃",person._id);
}else{
System.out.print("┗");
System.out.println(person._name);
getChildren(leader+" ",person._id);
}
}
}
getChildrenメソッドには、for文が2つあります。最初のfor文では、指定されたparentIdを持つレコード(兄弟)のリストを作っています。次のfor文で兄弟の一人一人について処理を行います。ArrayList<Person> alChildren = new ArrayList<Person>();
for(Person person:alPerson){
if(person._parentId==parentId){
alChildren.add(person);
}
}
int intCount=0;
for(Person person:alChildren){
intCount++;
System.out.print(leader);
if(intCount<alChildren.size()){
System.out.print("┣");
System.out.println(person._name);
getChildren(leader+"┃",person._id);
}else{
System.out.print("┗");
System.out.println(person._name);
getChildren(leader+" ",person._id);
}
}
}
2つ目のfor文では、ツリー構造を分かりやすく示すために罫線を使っています。
まず、leaderを表示します(最初の階層では何も表示しません)。
自分の下にも兄弟がいれば名前の前に「┣」を表示し、自分の名前を表示してからleaderに「┃」を追加し、getChildrenを呼び出します。
自分の下に兄弟がいなければ「┗」を表示し、自分の名前を表示してからleaderに全角スペースを追加してgetChildrenを呼び出します。
上のコードを実行すると、表示は次のようになります。
┗ナミヘイ
┣サザエ
┃┣タラ
┃┃┗タラコ
┃┗ブリ
┃ ┣ハマチ
┃ ┃┗イナダ
┃ ┗カンパチ
┣カツオ
┗ワカメ
┗ヒラメ
┣サザエ
┃┣タラ
┃┃┗タラコ
┃┗ブリ
┃ ┣ハマチ
┃ ┃┗イナダ
┃ ┗カンパチ
┣カツオ
┗ワカメ
┗ヒラメ
投稿:竹形 誠司[takegata]/2008年 06月 05日 05時 38分
/更新:2008年 06月 05日 05時 54分
ツリー構造の表示方法(JSPの場合)
by 竹形 誠司[takegata]
JSPの場合は、<%! と %>を使って内部クラスやフィールド、メソッドを記述します。こんな感じです。
<%@ page contentType="text/html; charset=utf-8"%>
<%@ page import = "java.util.ArrayList"%>
<HTML>
<HEAD><TITLE>tree</TITLE></HEAD>
<BODY>
<%!
class Person{
int _id;
int _parentId;
String _name;
Person(int id,int parentId,String name){
_id=id;
_parentId=parentId;
_name = name;
}
}
ArrayList<Person> alPerson = new ArrayList<Person>();
StringBuffer sb = new StringBuffer();
void getChildren(String leader,int parentId){
ArrayList<Person> alChildren = new ArrayList<Person>();
for(Person person:alPerson){
if(person._parentId==parentId){
alChildren.add(person);
}
}
int intCount=0;
for(Person person:alChildren){
intCount++;
sb.append(leader);
if(intCount<alChildren.size()){
sb.append("┣");
}else{
sb.append("┗");
}
sb.append(person._name);
sb.append("<BR>");
if(intCount<alChildren.size()){
getChildren(leader+"┃",person._id);
}else{
getChildren(leader+" ",person._id);
}
}
}
%>
<%
alPerson.add(new Person(1,0,"ナミヘイ"));
alPerson.add(new Person(2,1,"サザエ"));
alPerson.add(new Person(3,1,"カツオ"));
alPerson.add(new Person(4,1,"ワカメ"));
alPerson.add(new Person(5,2,"タラ"));
alPerson.add(new Person(6,4,"ヒラメ"));
alPerson.add(new Person(7,5,"タラコ"));
alPerson.add(new Person(8,2,"ブリ"));
alPerson.add(new Person(9,8,"ハマチ"));
alPerson.add(new Person(10,9,"イナダ"));
alPerson.add(new Person(11,8,"カンパチ"));
getChildren("",0);
%>
<DIV STYLE="line-height:16px;">
<%=sb.toString()%>
</DIV>
</BODY>
</HTML>
<%@ page import = "java.util.ArrayList"%>
<HTML>
<HEAD><TITLE>tree</TITLE></HEAD>
<BODY>
<%!
class Person{
int _id;
int _parentId;
String _name;
Person(int id,int parentId,String name){
_id=id;
_parentId=parentId;
_name = name;
}
}
ArrayList<Person> alPerson = new ArrayList<Person>();
StringBuffer sb = new StringBuffer();
void getChildren(String leader,int parentId){
ArrayList<Person> alChildren = new ArrayList<Person>();
for(Person person:alPerson){
if(person._parentId==parentId){
alChildren.add(person);
}
}
int intCount=0;
for(Person person:alChildren){
intCount++;
sb.append(leader);
if(intCount<alChildren.size()){
sb.append("┣");
}else{
sb.append("┗");
}
sb.append(person._name);
sb.append("<BR>");
if(intCount<alChildren.size()){
getChildren(leader+"┃",person._id);
}else{
getChildren(leader+" ",person._id);
}
}
}
%>
<%
alPerson.add(new Person(1,0,"ナミヘイ"));
alPerson.add(new Person(2,1,"サザエ"));
alPerson.add(new Person(3,1,"カツオ"));
alPerson.add(new Person(4,1,"ワカメ"));
alPerson.add(new Person(5,2,"タラ"));
alPerson.add(new Person(6,4,"ヒラメ"));
alPerson.add(new Person(7,5,"タラコ"));
alPerson.add(new Person(8,2,"ブリ"));
alPerson.add(new Person(9,8,"ハマチ"));
alPerson.add(new Person(10,9,"イナダ"));
alPerson.add(new Person(11,8,"カンパチ"));
getChildren("",0);
%>
<DIV STYLE="line-height:16px;">
<%=sb.toString()%>
</DIV>
</BODY>
</HTML>
投稿:竹形 誠司[takegata]/2008年 06月 05日 06時 03分
/更新:2008年 06月 05日 06時 03分