Ticket #58 (closed defect: fixed)

Opened 14 years ago

Last modified 14 years ago

IT商城产品搜索遇到 封装数据结构 的代码问题

Reported by: huangjianhua Owned by:
Priority: minor Milestone: 2011年5.1版本
Component: 系统相关 Version: 5.1
Keywords: IT商城 封装数据结构 产品搜索 Cc: huangzhong, chenyinle, liaojunqiang
Due Date: 16/12/2011

Description

在做产品搜索页面"品牌按拼音分组排序"筛选器的时候,遇到了一些代码上的问题:

在代码中,如何在后端封装数据返回给前台页面处理?

第一种做法是:

Map<String, List<SearcherGroup>> pinYinList = new LinkedHashMap<String, List<SearcherGroup>>();

采用以上方式封装,以Map中的参数String作为26个字母的一个Key,List<SearcherGroup?>作为Key所对应的Value;
而此时SearcherGroup的数据结构是如下所示:

public class SearcherGroup {
	String id;
	String name;
	int count;
	String  cId;
	
	//...SetX, getX  
	....
}

第二种做法是:

List<SearcherGroup> pinYinList = new ArrayList<SearchGroup>();

若采用以上方式封装数据返回页面的话,SearcherGroup? 则需要包含以上所说的Key,即标识26个字母的Key, 因此修改 SearchGroup? 的数据结构:

public class SearcherGroup {
	String id;
	String pinYinName;
	String name;
	int count;
	String  cId;
	
	//...SetX, getX  
	....
}

对于以上两种数据封装的结构,明显是第二种优于第一种的做法,第二种采用一个List就可以解决了,而不需要采用Map方式处理.

但是麻烦来了,以上两种做法所必须要面对前端对数据的展示:
代码如下:

<div class="allFat" id="J-allBrandList">
      <dl>
        <dd class="dat1">
			<span>A</span>
			<i>
				<a href="/mobile/changhong/" target="_self" id="mlink_39114">长虹</a>
				<a href="/mobile/skyworth/" target="_self" id="mlink_42376">创维</a>
				<a href="/mobile/cect/" target="_self" id="mlink_24387">CECT</a>
				<a href="/mobile/songlive/" target="_self" id="mlink_69671">盛浪</a>
			</i>
		</dd>	  
        <dd class="dat1">
			<span>B</span>
			<i>
				<a href="/mobile/changhong/" target="_self" id="mlink_39114">长虹</a>
				<a href="/mobile/skyworth/" target="_self" id="mlink_42376">创维</a>
				<a href="/mobile/cect/" target="_self" id="mlink_24387">CECT</a>
				<a href="/mobile/songlive/" target="_self" id="mlink_69671">盛浪</a>
			</i>
		</dd>
      </dl>
</div>

针对以上的代码,采用第一种的方式,在页面显示的时候,处理就比较简单了,两个循环就可以了,但是第一种做法做后端处理的时候,需要创建Map对象,而且在封装
Map<String, List<SearcherGroup?>>这个数据结构的时候,需要的代码量也多了.所分配给Map的空间也多.

然而针对第二种做法,在页面处理中需要比较复杂的代码去处理,本来是两个循环要解决的事情,现在需要一个循环来解决了,在页面的代码中做了如下的处理:

<div id="J-allBrandList" class="allFat">
  <dl>
  <%
	if(result.getPinYinList() != null){
		String curWord = "";
		StringBuilder s1 = new StringBuilder();
		for(int i = 0 ; i <result.getPinYinList().size(); i++){
			SearcherGroup bean = result.getPinYinList().get(i);
			String word = bean.getPinYinName().toUpperCase().substring(0,1);
			if(i>0 && !curWord.equals(word)){
				out.println("<dd><span>"+curWord+"</span><i>"+s1.toString()+"</i></dd>");
				s1 = new StringBuilder();
			}
			// Delete掉拼链接的代码
			....
			
			s1.append("<a id=\"mlink_92183\" target=\"_self\" href=\""+link+"\">"+bean.getName()+"</a>\n");
			
			//处理当品牌只有1个及处理最后一个的情况
			if(i == (result.getPinYinList().size()-1)){
				out.println("<dd><span>"+word+"</span><i>"+s1.toString()+"</i></dd>");
			}
			curWord = word;	//重置当前排序字母的值
  %>
	  <%}%>
  <% } %>
  </dl>
</div>

上面的代码应该没两个循环来处理的时候容易理解.

后端的对比:

1.第一种方式需要代码量比较多,采用Map所分配的空间也多.

2.第二种方式需要代码量少,采用List分配的空间也少.

前端的对比:

1.第一种方式,两个循环处理页面的显示,明显容易理解

2.第二种方式,一个循环做了两个循环的事,代码难于理解.

综上所述,两种封装数据结构的方式,各有利弊,在写代码的时候综合使用.

(以上代码若存在什么问题,欢迎批评指正.谢谢.)

Change History

comment:1 Changed 14 years ago by chenyinle

其实就是一个对数据分组的问题,从数据结构看,第一种需要一个Map,和多个List来表现;第二种只需要一个List表现。

comment:2 Changed 14 years ago by chenchongqi

  • Status changed from new to closed
  • Resolution set to fixed

comment:3 Changed 14 years ago by chenchongqi

我倾向第一种,首先第一种代码容易理解,其次第二种循环里还要做字符串匹配判断,没有什么性能上的优势,至于分配空间的问题,一次查询的这几十条完全可以忽略不计,一个查询方法执行完就是可以回收的了。

Note: See TracTickets for help on using tickets.