Implémenter la lecture du contact à partir du répertoire téléphonique à l'aide de Hashtable dans J2ME
Question
Je suis tombé sur un blocage dans lequel je devais trier les données lues depuis le PIM des téléphones. En faisant cela, j'ai perdu l'autre auquel chaque champ de contact était référencé au numéro de téléphone car j'ai utilisé 2 vecteurs distincts comme illustré ci-dessous
Avant de trier
Nna - +445535533
Ex - +373773737
Ab - +234575757
After sorting.(Which shouldn't be)
Ab - +445535533
Ex - +373773737
Nna - +234575757
Cela donne un comportement indésirable car le tri supprime l'index vers le pointeur d'index des vecteurs et un nom sélectionné (dans une zone de liste multiple) obtiendra un numéro erroné.
Alternativement,
J'ai utilisé une table de hachage, avec l'intention d'utiliser les noms comme clés et les nombres comme valeurs.
Mais cette association signifie que les noms en double utilisés comme clés ne seront pas autorisés. Ainsi, j'en ai fait un c'est-à-dire le numéro de téléphone comme clé à la place.
Je ne veux pas ressembler à un bébé qui pleure alors je m'arrête ici pendant un moment et donc vous le code avec l'espoir que vous le comprendrez
MA QUESTION
1. Existe-t-il un meilleur moyen / algorithme d'implémentation?
2. Comment implémenter getSelectedItems () de telle manière qu'il saisisse les numéros des index sélectionnés d'une MULTIPLE CHOICE LIST à partir d'une table de hachage
import java.util.Enumeration;
import java.util.Vector;
import java.util.Hashtable;
import javax.microedition.lcdui.List;
import javax.microedition.pim.Contact;
import javax.microedition.pim.ContactList;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMException;
/**
*
* @author nnanna
*/
public class LoadContacts implements Operation {
private boolean available;
private Vector telNames = new Vector();
Vector telNumbers = new Vector();
Hashtable Listcontact = new Hashtable();
private String[] names;
public Vector getTelNames() {
return telNames;
}
public Hashtable getListcontact() {
return Listcontact;
}
public void execute() {
try {
// go through all the lists
String[] allContactLists = PIM.getInstance().listPIMLists(PIM.CONTACT_LIST);
if (allContactLists.length != 0) {
for (int i = 0; i < allContactLists.length; i++) {
System.out.println(allContactLists[i]);
System.out.println(allContactLists.length);
loadNames(allContactLists[i]);
System.out.println("Execute()");
}
} else {
available = false;
}
} catch (PIMException e) {
available = false;
} catch (SecurityException e) {
available = false;
}
}
private void loadNames(String name) throws PIMException, SecurityException {
ContactList contactList = null;
try {
contactList = (ContactList) PIM.getInstance().openPIMList(PIM.CONTACT_LIST, PIM.READ_ONLY, name);
// First check that the fields we are interested in are supported(MODULARIZE)
if (contactList.isSupportedField(Contact.FORMATTED_NAME) && contactList.isSupportedField(Contact.TEL)) {
Enumeration items = contactList.items();
Hashtable temp = new Hashtable();
while (items.hasMoreElements()) {
Contact contact = (Contact) items.nextElement();
int telCount = contact.countValues(Contact.TEL);
int nameCount = contact.countValues(Contact.FORMATTED_NAME);
if (telCount > 0 && nameCount > 0) {
String contactName = contact.getString(Contact.FORMATTED_NAME, 0);
// go through all the phone availableContacts
for (int i = 0; i < telCount; i++) {
System.out.println("Read Telno");
int telAttributes = contact.getAttributes(Contact.TEL, i);
String telNumber = contact.getString(Contact.TEL, i);
Listcontact.put(telNumber, contactName);
temp.put(contactName, telNumber);
}
names = getSortedList();
// Listcontact = temp;
System.out.println(temp + "-------");
System.out.println(Listcontact + "*******");
shortenName(contactName, 20);
}
available = true;
}
} else {
available = false;
}
} finally {
// always close it
if (contactList != null) {
contactList.close();
}
}
}
private void shortenName(String name, int length) {
if (name.length() > length) {
name = name.substring(0, 17) + "...";
}
}
public Vector getSelectedItems(List lbx) {
boolean[] arrSel = new boolean[lbx.size()];
Vector selectedNumbers = new Vector();
int selected = lbx.getSelectedFlags(arrSel);
String selectedString;
String result = "";
for (int i = 0; i < arrSel.length; i++) {
if (arrSel[i]) {
selectedString = lbx.getString(lbx.getSelectedFlags(arrSel));
result = result + " " + i;
System.out.println(Listcontact.get(selectedString));
// System.out.println(telNumbers.elementAt(i));
}
}
return selectedNumbers;
}
private String[] sortResults(String data[]) {
RecordSorter sorter = new RecordSorter();
boolean changed = true;
while (changed) {
changed = false;
for (int j = 0; j < (data.length - 1); j++) {
String a = data[j], b = data[j + 1];
if (a != null && b != null) {
int order = sorter.compare(a.getBytes(), b.getBytes());
if (order == RecordSorter.FOLLOWS) {
changed = true;
data[j] = b;
data[j + 1] = a;
}
}
}
}
return data;
}
public String[] getNames() {
return names;
}
Vector elements = new Vector();
private String[] getValueArray(Hashtable value) {
System.out.println(Listcontact + " c");
Enumeration e = value.elements();
while (e.hasMoreElements()) {
elements.addElement(e.nextElement());
}
String[] elementsArray = new String[elements.size()];
elements.copyInto(elementsArray);
elements.removeAllElements();
System.out.println(elementsArray + " k");
return elementsArray;
}
public void getDuplicates(Vector realValue) {
Vector duplicate = new Vector();
Enumeration e = realValue.elements();
for (int i = 0; e.hasMoreElements(); i++) {
if (duplicate.isEmpty() || !duplicate.elementAt(i).equals(e.nextElement())) {
break;
} else {
duplicate.addElement(e.nextElement());
}
}
}
public String[] getSortedList() {
return sortResults(getValueArray(Listcontact));
}
}
La solution
Permettez-moi de répéter votre exigence: vous voulez une méthode qui triera les contacts lus dans le répertoire natif, puis les triera par ordre alphabétique par nom.
Voici l'approche,
Remplacez les vecteurs et les tables de hachage de votre code par un seul vecteur, disons contactListVector
, contenant des éléments de type ContactItem
, ne vous inquiétez pas, cette classe est expliquée ci-dessous. Fondamentalement, le nom et le numéro (s) du contact sont liés ensemble dans un ContactItem
, vous n'avez donc pas à vous soucier des mappages qui réduisent l'utilisation de structures de données redondantes.
class ContactItem {
private String name;
private String tnumber; //this can also be a data structure
//for storing multiple numbers
ContactItem( String name, String tnumber) {
this.name = name;
this.tnumber = tnumber;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTnumber() {
return tnumber;
}
public void setTnumber(String tnumber) {
this.tnumber = tnumber;
}
}
Vous pouvez réutiliser l'algorithme de tri sur contactListVector
en comparant la variable membre ContactItem.name
de l'élément vectoriel. Vous pouvez également déployer différents types sur les variables membres nombres et / ou noms . De plus, il existe de nombreuses bibliothèques pour JavaME disponibles qui ont de meilleurs algorithmes de tri implémentés si nécessaire, utilisez-les.
Je vous recommande d'effectuer le tri une fois sur les éléments contactListVector
à la fin de votre méthode loadNames(...)
peut-être dans le bloc finally déclenché par une variable booléenne. L'appel de tri actuel dans chaque itération sur l'énumération items
est coûteux et prend du temps.
Vous pouvez également sérialiser / désérialiser le ContactItem
ainsi conserver votre liste de contacts.
Faites-moi savoir si vous avez besoin d'explications détaillées.
Autres conseils
Qu'en est-il de l'insertion du nom et des numéros du contact dans un recordStore, pour pouvoir ensuite effectuer un tri en créant une classe qui implémente RecordComparator
.
Cette déclaration dans votre code n'a aucun sens:
selectedString = lbx.getString(lbx.getSelectedFlags(arrSel))
Par La documentation de l'API lcdui List ci-dessus renverra la chaîne située à l'index égal à le nombre d'éléments sélectionnés pourquoi en auriez-vous besoin?
Si vous devez afficher le texte sélectionné à des fins de débogage, utilisez plutôt lbx.getString(i)
.
Pour implémenter getSelectedItems () de telle manière qu'il saisisse les numéros des index sélectionnés d'une MULTIPLE CHOICE LIST , procédez comme suit:
public Vector getSelectedItems(List lbx) {
boolean[] arrSel = new boolean[lbx.size()];
Vector selectedNumbers = new Vector();
int selected = lbx.getSelectedFlags(arrSel);
System.out.println("selected: [" + selected + "] elements in list");
String selectedString;
String result = "";
for (int i = 0; i < arrSel.length; i++) {
if (arrSel[i]) {
// here, i is the selected index
selectedNumbers.addElement(new Integer(i)); // add i to result
String selectedString = lbx.getString(i);
System.out.println("selected [" + selectedString
+ "] text at index: [" + i + "]");
}
}
return selectedNumbers;
}
En ce qui concerne les besoins de tri, déposez simplement le HashTable
et utilisez le Vector
d'objets correctement conçus à la place, comme suggéré dans une autre réponse -avec votre propre algorithme de tri ou celui d'une bibliothèque J2ME tierce.
Je vous suggère d'avoir une classe Contact
avec nom et vecteur de nombres.Et au lieu de trier le tableau des noms, triez le tableau des contacts.