按首字母分类并排序显示的列表(二)--给BaseExpandableListAdapter提供数据的HashList

前言:前一篇文章说道的BaseExpandableListAdapter类的许多函数都通过调用helper.getHashList()这个函数用到了HashList类的数据,下面来介绍HashList。

一、首先看HashList的职责:


(一)对两种数据的封装:
1.歌曲名字首字母的集合-->keys
2.每个首字母与相应歌曲集合的映射-->maps
(二)对这些数据的操作
1.基于groupId和childId返回相应的实例
2.对keys的排序
3.对keys和maps的添加和移除


二、HashList类的变量:

2.1、代码

	/**
	 * 键值集合
	 * */
	private List<K> keys = new ArrayList<K>();
	/**
	 * 键值对映射
	 * 一个K对应一个group
	 */	
	private HashMap<K, List<V>> map = new HashMap<K, List<V>>();
	/**
	 * 键值分类
	 */
	private KeySort<K, V> keySort;


2.2、HashList类中的map这个变量的数据结构示意图:

String对应了K,Mp3Info对应了V;


2.3、Mp3Info就是歌曲的实体类,声明代码如下:

package guoke.model;

import java.io.Serializable;
import java.util.List;
/*
 * 一个mp3的实体类 
 */
public class Mp3Info implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String id;
	private String mp3Name; //mp3名字
	private long mp3Size;   //mp3大小
	private String lrcName;
	private String lrcSize;
	private String url;     //音乐uri
	private String title;   //音乐标题
	private long mdstore_id;//媒体库的id
	private long Duration;  //时长
	private String artist;  //艺术家
	private String album;   //专辑 
	private long albumId;   //专辑ID 
	private Boolean ischecked;
	private Boolean isPrePare=false;
	
	public Boolean getIsPrePare() {
		return isPrePare;
	}

	public void setIsPrePare(Boolean isPrePare) {
		this.isPrePare = isPrePare;
	}

	public Boolean getIschecked() {
		return ischecked;
	}

	public void setIschecked(Boolean ischecked) {
		this.ischecked = ischecked;
	}

	public String getAlbum() {
		return album;
	}

	public void setAlbum(String album) {
		this.album = album;
	}

	public long getAlbumId() {
		return albumId;
	}

	public void setAlbumId(long albumId) {
		this.albumId = albumId;
	}

	
	
	/**
	 * @return the artist
	 */
	public String getArtist() {
		return artist;
	}

	/**
	 * @param artist the artist to set
	 */
	public void setArtist(String artist) {
		this.artist = artist;
	}

	/**
	 * @return the title
	 */
	public String getTitle() {
		return title;
	}

	/**
	 * @param title the title to set
	 */
	public void setTitle(String title) {
		this.title = title;
	}

	
	/**
	 * @return the duration
	 */
	public long getDuration() {
		return Duration;
	}

	/**
	 * @param duration the duration to set
	 */
	public void setDuration(long duration) {
		Duration = duration;
	}

	/**
	 * @return the mdstore_id
	 */
	public long getMdstore_id() {
		return mdstore_id;
	}

	/**
	 * @param mdstore_id the mdstore_id to set
	 */
	public void setMdstore_id(long mdstore_id) {
		this.mdstore_id = mdstore_id;
	}

	/**
	 * @return the url
	 */
	public String getUrl() {
		return url;
	}

	/**
	 * @param url the url to set
	 */
	public void setUrl(String url) {
		this.url = url;
	}

	private  List<Mp3Info> mp3InfosList = null;

	/**
	 * @return the mp3InfosList
	 */
	public List<Mp3Info> getMp3InfosList() {
		return mp3InfosList;
	}

	/**
	 * @param mp3InfosList the mp3InfosList to set
	 */
	public void setMp3InfosList(List<Mp3Info> mp3InfosList) {
		this.mp3InfosList = mp3InfosList;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public Mp3Info() {
		super();
	}

	@Override
	public String toString() {
		return "Mp3Info [id=" + id + ", lrcName=" + lrcName + ", lrcSize="
				+ lrcSize + ", mp3Name=" + mp3Name + ", mp3Size=" + mp3Size
				+ ", mp3Size=" + url +"]";
	}

	public String getMp3Name() {
		return mp3Name;
	}

	public Mp3Info(String id, String mp3Name, long mp3Size, String lrcName,
			String lrcSize,String url) {
		super();
		this.id = id;
		this.mp3Name = mp3Name;
		this.mp3Size = mp3Size;
		this.lrcName = lrcName;
		this.lrcSize = lrcSize;
		this.url=url;
	}

	public void setMp3Name(String mp3Name) {
		this.mp3Name = mp3Name;
	}

	public long getMp3Size() {
		return mp3Size;
	}

	public void setMp3Size(long mp3Size) {
		this.mp3Size = mp3Size;
	}

	public String getLrcName() {
		return lrcName;
	}

	public void setLrcName(String lrcName) {
		this.lrcName = lrcName;
	}

	public String getLrcSize() {
		return lrcSize;
	}

	public void setLrcSize(String lrcSize) {
		this.lrcSize = lrcSize;
	}

	
}

2.4、HashList类中的KeySort是一个接口,,声明的代码:

/***
 * 分类接口,根据V value返回K key
 *
 * @param <K>
 * @param <V>
 */

public interface KeySort<K, Mp3Info> {
	public K getKey(Mp3Info mp3Info);
}

2.5、KeySort接口只带了一个函数 getKey(),该函数能获取Mp3Info实例的首字母,也就是获取歌曲的首字母




三、HashList类的函数:

3.1、代码

	/**
	 * 构造函数
	 */
	public HashList(KeySort<K, V> keySort) {
		// TODO Auto-generated constructor stub
		this.keySort = keySort;
	}

	/**
	 * 根据value值返回key
	 * 返回首字母的大写字母
	 */	
	public K getKey(V v) {
		//在AssortPinyinList类里实现了KeySort接口的getkey()函数
		//返回名字的首字母的大写字母
		return keySort.getKey(v);
	}


	/** 
	 * 返回大写的首字母,根据int类型的id
	 */
	public K getKeyIndex(int key) {
		//key存储着每个group对应的id
		//一个group对应着一个key
		//key--group--id
		return keys.get(key);
	}
	
	/**
	 * 获取首字母的集合
	 */
	public List<K> getKeys(){
		return keys;
	}

	/** 
	 * 根据索引返回键值对,返回的是一组child
	 */

	public List<V> getChildList(int key) {
		//得到group的id,map存储着List<V>
		//源头还是从kerArr那里获得键值,即人名的首字母大写
		//在从map里去映射的list
		return map.get(getKeyIndex(key));
	}

	
	/**
	 * 取得V的实例
	 * key就是 group_id
	 * value就是 child_id
	 * @return 一个V类型的实例
	 */
	public V getChild(int key, int value) {
		//先得到group的id,再得到该group下的child的id
		return getChildList(key).get(value);

	}

	/**获取keys的长度*/
	public int size() {
		return keys.size();
	}
	
	/** 取得k的下标*/
	public int indexOfKey(K k)
	{
		return keys.indexOf(k);
	}

	/** 清除所有实例*/
	public void clear() {
		for (Iterator<K> it = map.keySet().iterator(); it.hasNext(); map.remove(it.next()));
	}

	/**
	 * 在这里实现了分类
	 * 把每一个名字分到对应的group里面
	 */
	public boolean add(Object object) {
		V v = (V) object;
		K key = getKey(v);
		//System.out.println("在add()里,key:"+key);
		//
		if (!map.containsKey(key)) {
			//该list存放人名
			List<V> list = new ArrayList<V>();
			//添加人名到list
			list.add(v);
			//添加该人名的首大写字母
			keys.add(key);
			//
			map.put(key, list);
		} else {
			//
			map.get(key).add(v);
		}
		return false;
	}
		
	/**
	 * 移除 List<V>里的实例
	 */
	public boolean remove(Object v) {
		// TODO Auto-generated method stub
		//取得k
		K k=getKey((V)v);
		//取得k的下标
		int k_index=indexOfKey(k);
		
		//根据k的下标取得对应的子list,移除该对象
		boolean b=getChildList(k_index).remove(v);
		//如果k的下标对应的子list为空,移除k
		if(getChildList(k_index).isEmpty()==true){
			keys.remove(k);
		}
		return b;
	}
	
	/** 键值对排序 */
	public void sortKeyComparator(Comparator<K> comparator) {
		//对keyArr的元素以comparator定义的方式来排序
		//即对group对应的key进行排序
		Collections.sort(keys, comparator);
		if(keys.contains("#")){
			keys.remove("#");
			keys.add((K) "#");
		}
	}
这些函数的作用就是:

1.基于groupId和childId返回相应的实例
2.对keys的排序
3.对keys和maps的添加和移除


此时可知HashList封装了比较见到的一些函数操作,我们在Mp3SortHelper类里封装一些对HashList的数据更复杂的操作,主要是排序:

3.2、Mp3SortHelper代码:

package guoke.sort_helper;

import guoke.model.Mp3Info;
import guoke.sort_map_uitls.HashList;
import guoke.sort_map_uitls.KeyComparator;
import guoke.sort_map_uitls.KeySort;
import guoke.sort_map_uitls.Mp3ListComparator_CN;
import guoke.sort_map_uitls.Mp3ListComparator_EN;

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

import net.sourceforge.pinyin4j.PinyinHelper;

/**
 * 封装了对HashList的一下复杂的操作,主要是排序
 * */
public class Mp3SortHelper {
	
	private List<Mp3Info> mp3List;
	
	private Mp3ListComparator_CN mp3ListSort_CN = new Mp3ListComparator_CN();
	private Mp3ListComparator_EN mp3ListSort_EN= new Mp3ListComparator_EN();
	private KeyComparator keySort = new KeyComparator();
	
	
	//1.声明并实例化HashList<String,String>这个类
	private HashList<String,Mp3Info> hashList=new HashList<String,Mp3Info>
		(   //2.同时实例化 接口
			new KeySort<String,Mp3Info>()
			{    
				//3.实例化了接口的函数
				public String getKey(Mp3Info mp3Info)
				{
					return getFirstChar(mp3Info.getTitle());
				}
			}
		);
	
	/**
	 * 构造函数,调用了add_And_sortMp3()函数
	 * 将mp3Infos添加到hashList,同时实现了排序
	 * */
	public Mp3SortHelper(List<Mp3Info> sList){
		this.mp3List=sList;
		add_And_sortMp3();
	}
	
	/**
	 * 添加并排序
	 * */
	private void add_And_sortMp3(){
		// 分类
		//str 代表数组中元素类型,从数组中第一个元素开始遍历,strList代表被遍历的数组名
		for (Mp3Info mp3Info : mp3List) {
			//调用的add()函数里面实现了分类功能
			//每一次添加一个str都会对该str归类
			hashList.add(mp3Info);
			System.out.println("title = "+mp3Info.getTitle()+" getFirst = "+getFirstChar(mp3Info.getTitle()));
		}
		hashList.sortKeyComparator(keySort);
		for(int i=0,length=hashList.size();i<length;i++)
		{   
			<span style="color:#ff0000;">//真正在执行排序的代码在这里
			//给每一个group的item排序,先排序英文,在排序中文
			Collections.sort(hashList.getChildList(i),mp3ListSort_EN);
			Collections.sort(hashList.getChildList(i),mp3ListSort_CN);</span>		
		}
	}
	
	//获得字符串的首字母 首字符 转汉语拼音
	public  String getFirstChar(String value) {
			// 首字符
			char firstChar = value.charAt(0);
			// 首字母分类
			String first = null;
			// 是否是非汉字
			String[] print = PinyinHelper.toHanyuPinyinStringArray(firstChar);

			if (print == null) {
				// 将小写字母改成大写
				if ((firstChar >= 97 && firstChar <= 122)) {
					firstChar -= 32;
				}
				if (firstChar >= 65 && firstChar <= 90) {
					first = String.valueOf((char) firstChar);
				} else {
					// 认为首字符为数字或者特殊字符
					first = "#";
				}
			} else {
				// 如果是中文 分类大写字母
				first = String.valueOf((char)(print[0].charAt(0) -32));
			}
			if (first == null) {
				first = "?";
			}
			return first;
		}

	
	/**
	 * 返回上面定义 hashList对象	
	 * */
	public HashList<String, Mp3Info> getHashList() {
			return hashList;
		}
	
	/**
	 * 汇总HashList中已排好序mp3Info到mp3Infos
	 * @return mp3Infos 汇总好的列表
	 * */
	public List<Mp3Info> getMp3InfosFromHashList(){
		List<Mp3Info> mp3Infos=new ArrayList<Mp3Info>();
		List<String> keys = hashList.getKeys();
		for(int i = 0;i<keys.size();i++){//遍历每一个首字母对应的列表
			List<Mp3Info> temps = hashList.getChildList(i);
			for(int j=0;j<temps.size();j++){//遍历每个列表,组个添加,完全顺序
				mp3Infos.add(hashList.getChild(i, j)); 
			}
		}
		return mp3Infos;
	}
	
}


其中Mp3ListComparator_CN,Mp3ListComparator_EN和KeyComparator三个类分别是针对中文歌曲名,英文歌曲名和keys排序的比较函数,后面有时间再详细介绍.


Mp3SortHelper类起到的作用:
一.对hashList实例的封装
1.实例化一个hashList对象,并实现KeySort接口的
回调函数getkeys(),在hashList内部调用;
二.一些辅助操作
2.实现getFirst()函数,获取字符串的首字母
3.实现getMp3InfosFromHashList函数,
从hashList实例中提取出mp3Infos实例

 

BaseExpandableListAdapter通过Mp3SortHelper类对HashList类进行操作


四、代码模块结构图:











  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值