Aller au contenu

gestion de List<String> et récupération des éléments


tammikuu

Recommended Posts

Bonjour, j'aurais besoin de précisions sur l'usage des List<String> et plus particulièrement sur la récupération d'un élément de la liste.

Mon problème est que j'ai créer un liste de string (récupéré dans un tableau html) et je voudrais re-trier les cellules :


public List<String> ExtractCells() {
List<String> cells = new ArrayList<String>(nCells);
Pattern p=Pattern.compile("<td[^>]*>(.*)</td>");
Matcher m=p.matcher(table);
while(m.find()){cells.add(m.group());}
return cells;
}

public List<String> ExtractOrigins() {
List<String> origins = new ArrayList<String>(nColumns);
for (int i=0; i<nColumns; i++) {origins.add(i, cells.get(i));}
return origins;
}

or la fonction me retourne une liste vide ...

même problème avec :


public List<String> ExtractOrigins() {
List<String> origins = new ArrayList<String>(nColumns);
for (int i=0; i<nColumns; i++) {
String origin = cells.get(i).toString();
origins.add(i,origin);
}
return origins;
}

PS : je verifie le contenu avec un toast:

Toast toast;

toast = Toast.makeText(getApplicationContext(),origins.toString(), Toast.LENGTH_LONG);
toast.show();

Lien vers le commentaire
Partager sur d’autres sites

Es-tu sûr de ton expression régulière ? Extrait elle quelque chose réellement ?

PS: ta question est plutot d'ordre générale Java, pas spécifique Activity, Service, et serai plus à sa place dans la section Développement/Autres

Lien vers le commentaire
Partager sur d’autres sites

Désoler pour la section (je ne maîtrise pas trop la différence Java/Android)...

ExctractCells() me renvoi bien une liste contenant "le contenu des cellules"...

c'est lorsque je veux récupérer un élément n de la liste qu'il ne se passe rien...

je te post l'ensemble du code si ça peut aider ...



package com.polytech.calendrier;



import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;


public class Dates extends Activity{
String url = ("http://www.univ-orleans.fr/polytech/index.php?fileId=Polytech/Formations/Specialisation_EO/Recrutement");
String site = GetHtml(url);
String table = ExtractTable();
List<String> headers = ExtractHeaders();
List<String> cells = ExtractCells();
List<String> origins = ExtractOrigins();
List<String> informations = ExtractInformations();
int nLines = CountLines();
int nColumns = CountColumns();
int nCells = CountCells();

public void Tests() {
Toast toast;
// toast = Toast.makeText(getApplicationContext(),CleanHtml(site), Toast.LENGTH_LONG);
// toast.show();
// toast = Toast.makeText(getApplicationContext(),(table), Toast.LENGTH_LONG);
// toast.show();
// toast = Toast.makeText(getApplicationContext(),"nombre de colonnes : "+nColumns, Toast.LENGTH_LONG);
// toast.show();
// toast = Toast.makeText(getApplicationContext(),"nombre de lignes : "+nLines, Toast.LENGTH_LONG);
// toast.show();
// toast = Toast.makeText(getApplicationContext(),"nombre de cellules : "+nCells, Toast.LENGTH_LONG);
// toast.show();
// toast = Toast.makeText(getApplicationContext(),CleanHtml(headers.toString()), Toast.LENGTH_LONG);
// toast.show();
// toast = Toast.makeText(getApplicationContext(),cells.toString(), Toast.LENGTH_LONG);
// toast.show();
toast = Toast.makeText(getApplicationContext(),origins.toString(), Toast.LENGTH_LONG);
toast.show();
// toast = Toast.makeText(getApplicationContext(),informations.toString(), Toast.LENGTH_LONG);
// toast.show();
}

protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState);
setContentView(R.layout.dates);

Spinner spinner=((Spinner)findViewById(R.id.spinSelectView));
final TextView textView=((TextView)findViewById(R.id.textViewSite));

Tests();

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, origins);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
textView.setText(CleanHtml(informations.get(position).toString())); 
}
public void onNothingSelected(AdapterView<?> parent) {
textView.setText("sélectionnez une filière d'origine");
}
});
}

public String GetHtml(String url) {
InputStream content = null;
String contentString="problème de connexion";
try {
HttpGet httpGet = new HttpGet(url);
HttpClient httpclient = new DefaultHttpClient();
// Execute HTTP Get Request
HttpResponse response = httpclient.execute(httpGet);
content = response.getEntity().getContent();
BufferedReader rd = new BufferedReader(new InputStreamReader(content), 4096);
String line;
StringBuilder sb =  new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
contentString = sb.toString();
} catch (Exception e) {
Toast toast = Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG);
toast.show();
}
return contentString;
}

public String CleanHtml(String source) {
String clean = source.replaceAll("<[^>]*>", " ");
return clean;
}

public String ExtractTable() {
String table="";
Pattern p=Pattern.compile("<table[^>]*>(.*)</table>");
Matcher m=p.matcher(site);
while(m.find()){table += m.group();}
if (table != "") {return table;}
else {return "erreur de syntaxe";}
}

public List<String> ExtractHeaders() {
List<String> headers = new ArrayList<String>();
Pattern p=Pattern.compile("<th[^>]*>(.*)</th>");
Matcher m=p.matcher(table);
while(m.find()){headers.add(m.group());}
return headers;
}

public List<String> ExtractCells() {
List<String> cells = new ArrayList<String>(nCells);
Pattern p=Pattern.compile("<td[^>]*>(.*)</td>");
Matcher m=p.matcher(table);
while(m.find()){cells.add(CleanHtml(m.group()));}
return cells;
}

public List<String> ExtractOrigins() {
List<String> origins = new ArrayList<String>(nColumns);
for (int i=0; i<nColumns; i++) {
String origin = cells.get(i).toString();
origins.add(origin);
}
return origins;
}

public List<String> ExtractInformations() {
List<String> informations = new ArrayList<String>(nColumns);
for (int i=0; i<nColumns; i++) {
String info="";
for (int j=0; j<nCells; j++){
info = cells.get(i+nColumns);
if ((i+nColumns)*j < nCells){
info += cells.get((i+nColumns)*j);
}
}
informations.add(i, CleanHtml(info));
}
return informations;
}

public int CountColumns() {
int nColumns=0;
Pattern p=Pattern.compile("</th>");
Matcher m=p.matcher(table);
while(m.find()){nColumns++;}
return nColumns;
}

public int CountLines() {
int nLines=0;
Pattern p=Pattern.compile("</tr>");
Matcher m=p.matcher(table);
while(m.find()){nLines++;}
return nLines-1;
}

public int CountCells() {
int nCells=0;
Pattern p=Pattern.compile("</td>");
Matcher m=p.matcher(table);
while(m.find()){nCells++;}
return nCells;
}
}


Lien vers le commentaire
Partager sur d’autres sites

int nColumns est bien renseigné au moment de l'appel à la méthode extractOrigins ?

Si je ne me trompe pas, dans ta classe tu initialise des variables directement avec l'appel de méthodes :

List<String> headers = ExtractHeaders();

List<String> cells = ExtractCells();

List<String> origins = ExtractOrigins();

List<String> informations = ExtractInformations();

int nLines = CountLines();

int nColumns = CountColumns();

int nCells = CountCells();

le problème est que dans la première méthode appellée (ExtractOrigins()), on utilise la variable nColumns qui n'est pas encore initialisée.

Cela compile très bien mais au moment ou ExtractOrigins est lancé, la valeur est encore celle par défaut pour un int, soit "0".

Il vaudrait mieux à mon sens, dans la classe créé les variables (éventuellement instancié les new ArrayList() )

Et dans ton "main" ou ton Activity, tu initialises leurs valeurs.

Si ensuite tu procèdes de la sorte :

protected void onCreate(Bundle savedInstanceState) {

... bla bla bla bla bla

// initialisation des variables

int nbColums = countColumns();

list machin = ExtractOrigins (nbColumns);

ExtractOrigines(int nBColumns)

tu n'auras plus de problèmes d'utiliser une variable de classe non encore initialisée.

Lien vers le commentaire
Partager sur d’autres sites

Exact ! Merci je ne l'avais même pas vu...

J'ai maintenant un problème de dimension dans cette même fonction.

Juste pour info, lorsque l'on fait :


public List<String> ExtractOrigins() {
List<String> origins = new ArrayList<String>(nColumns);
for (int i=0; i<nColumns; i++) {
String origin = cells.get(i).toString();
origins.add(origin);
}
return origins;
}

la fonction

origins.add(origin);

ajoute bien un élément à la liste ? si oui la dimension de la liste doit etre incrémentée ?

car il me dit :


10-11 18:24:31.466: ERROR/AndroidRuntime(5009): Caused by: java.lang.IndexOutOfBoundsException: Invalid location 1, size is 1

Lien vers le commentaire
Partager sur d’autres sites

La méthode add ajoute bien l'élément à la fin de la liste, et augmente si besoin est la taille allouée à la liste; pas besoin de gérer cela soi-même

A mon avis, l'erreur se produit plutôt sur la ligne précédente, sur le cells.get(i)

Lien vers le commentaire
Partager sur d’autres sites

l'erreur viens bien de la fonction ExtractOrigins.

Pour résumer, je veux récupérer un tableau sur une page web, = OK

extraire les headers = OK

récuperer la ligne suivante (origines) dans une liste afficher les cellules dans un menu déroulant = ERREUR

afficher dans un textview le contenu des lignes suivantes(informations) (pour chaque colonne en fonction de la colone de séléctionnée dans le menu déroulant) = NON TESTE


package com.polytech.calendrier;



import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;


public class Dates extends Activity{
String url = ("http://www.univ-orleans.fr/polytech/index.php?fileId=Polytech/Formations/Specialisation_EO/Recrutement");
String site = GetHtml(url);
String table = ExtractTable();
int nLines = CountLines();
int nColumns = CountColumns();
int nCells = CountCells();
List<String> headers = ExtractHeaders();
List<String> cells = ExtractCells();
// List<String> origins = ExtractOrigins();
// List<String> informations = ExtractInformations();

public void Tests() {
Toast toast;
toast = Toast.makeText(getApplicationContext(),CleanHtml(site), Toast.LENGTH_LONG);
toast.show();
toast = Toast.makeText(getApplicationContext(),(table), Toast.LENGTH_LONG);
toast.show();
toast = Toast.makeText(getApplicationContext(),"nombre de colonnes : "+nColumns, Toast.LENGTH_LONG);
toast.show();
toast = Toast.makeText(getApplicationContext(),"nombre de lignes : "+nLines, Toast.LENGTH_LONG);
toast.show();
toast = Toast.makeText(getApplicationContext(),"nombre de cellules : "+nCells, Toast.LENGTH_LONG);
toast.show();
toast = Toast.makeText(getApplicationContext(),CleanHtml(headers.toString()), Toast.LENGTH_LONG);
toast.show();
toast = Toast.makeText(getApplicationContext(),cells.toString(), Toast.LENGTH_LONG);
toast.show();
// toast = Toast.makeText(getApplicationContext(),origins.toString(), Toast.LENGTH_LONG);
// toast.show();
// toast = Toast.makeText(getApplicationContext(),informations.toString(), Toast.LENGTH_LONG);
// toast.show(); 
}

protected void onCreate(Bundle savedInstanceState) { 
super.onCreate(savedInstanceState);
setContentView(R.layout.dates);

Spinner spinner=((Spinner)findViewById(R.id.spinSelectView));
final TextView textView=((TextView)findViewById(R.id.textViewSite));

Tests();

// ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, origins);
// adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// spinner.setAdapter(adapter);
// spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
// public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// textView.setText(CleanHtml(informations.get(position).toString())); 
// }
// public void onNothingSelected(AdapterView<?> parent) {
// textView.setText("sélectionnez une filière d'origine");
// }
// });
}

public String GetHtml(String url) {
InputStream content = null;
String contentString="problème de connexion";
try {
HttpGet httpGet = new HttpGet(url);
HttpClient httpclient = new DefaultHttpClient();
// Execute HTTP Get Request
HttpResponse response = httpclient.execute(httpGet);
content = response.getEntity().getContent();
BufferedReader rd = new BufferedReader(new InputStreamReader(content), 4096);
String line;
StringBuilder sb =  new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
contentString = sb.toString();
} catch (Exception e) {
Toast toast = Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG);
toast.show();
}
return contentString;
}


public String CleanHtml(String source) {
String clean = source.replaceAll("<[^>]*>", " ");
return clean;
}

public String ExtractTable() {
String table="";
Pattern p=Pattern.compile("<table[^>]*>(.*)</table>");
Matcher m=p.matcher(site);
while(m.find()){table += m.group();}
if (table != "") {return table;}
else {return "erreur de syntaxe";}
}

public List<String> ExtractHeaders() {
List<String> headers = new ArrayList<String>();
Pattern p=Pattern.compile("<th[^>]*>(.*)</th>");
Matcher m=p.matcher(table);
while(m.find()){headers.add(m.group());}
return headers;
}

public List<String> ExtractCells() {
List<String> cells = new ArrayList<String>(nCells);
Pattern p=Pattern.compile("<td[^>]*>(.*)</td>");
Matcher m=p.matcher(table);
while(m.find()){cells.add(CleanHtml(m.group()));}
return cells;
}

public List<String> ExtractOrigins() {
List<String> origins = new ArrayList<String>(nColumns);
for (int i=0; i<nColumns; i++) {
String origin = cells.get(i).toString();
origins.add(origin);
}
return origins;
}

public List<String> ExtractInformations() {
List<String> informations = new ArrayList<String>(nColumns);
for (int i=0; i<nColumns; i++) {
String info="";
for (int j=0; j<nCells; j++){
info = cells.get(i+nColumns);
if ((i+nColumns)*j < nCells){
info += cells.get((i+nColumns)*j);
}
}
informations.add(i, CleanHtml(info));
}
return informations;
}

public int CountColumns() {
int nColumns=0;
Pattern p=Pattern.compile("</th>");
Matcher m=p.matcher(table);
while(m.find()){nColumns++;}
return nColumns;
}

public int CountLines() {
int nLines=0;
Pattern p=Pattern.compile("</tr>");
Matcher m=p.matcher(table);
while(m.find()){nLines++;}
return nLines-1;
}

public int CountCells() {
int nCells=0;
Pattern p=Pattern.compile("</td>");
Matcher m=p.matcher(table);
while(m.find()){nCells++;}
return nCells;
}

}

Lien vers le commentaire
Partager sur d’autres sites

l'erreur viens du fait cells à une dimension de 1, or je ne me l'explique pas puisque je créer une liste de taille "nCells",

a moins que ce parametre ne determine que la capacité max de la liste mais quand bien même il récupère chaque cellule et l'ajoute a cells non ?


List<String> cells = new ArrayList<String>(nCells);
Pattern p=Pattern.compile("<td[^>]*>(.*)</td>");
Matcher m=p.matcher(table);
while(m.find()){cells.add(CleanHtml(m.group()));}
return cells;

cette fonction se comporte comme si elle prennait toutes les balises et les mettait dans une seule String de cells...

Lien vers le commentaire
Partager sur d’autres sites

As-tu corrigé ton problème ?

Si je recopie ton erreur plus haut :

10-11 18:24:31.466: ERROR/AndroidRuntime(5009): Caused by: java.lang.IndexOutOfBoundsException: Invalid location 1, size is 1

L'exception dit "IndexOutOfBounds" ce qui signifie que tu essaie de lire au delà des limites du tableau/list

Il te dit que la taille du tableau (size) est de 1.

Et il te dit également que tu essaie de lire une valeur à la position 1.

Hors un tableau de taille 1 n'a qu'un élément à la position 0.

Ce qui veut dire que tu as une nColumns supérieur à 1 et que ton tableau de cellls à une taille de 1.

D'ou le problème

Lien vers le commentaire
Partager sur d’autres sites

oui j'ai bien compris cf post precedant, la question devient donc pourquoi la fonction suivante concatène toutes les cellules dans un seul String (le premier de cells avec un indice 0) ...

List<String> cells = new ArrayList<String>(nCells);

Pattern p=Pattern.compile("<td[^>]*>(.*)</td>");

Matcher m=p.matcher(table);

while(m.find()){cells.add(CleanHtml(m.group()));}

return cells;

Lien vers le commentaire
Partager sur d’autres sites

Resolu, l'erreur vient du fait que while(m.find()){..} ne fait qu'un tour car il récupere toute les occurence du motif d'un coup, l'astuce est de passer par un scanner en utilisant le bon séparateur de "mot"

public List<String> ExtractHeaders() {
List<String> headers = new ArrayList<String>();
Scanner sc = new Scanner(table);
sc.useDelimiter("><");
Pattern p=Pattern.compile("th[^>]*>(.*)</th");
while(sc.hasNext()){
String mot = sc.next();  
Matcher m = p.matcher(mot);
while(m.find()){headers.add(CleanHtml(m.group()));}
}
return headers;
}

par contre il laisse du coup des résidus de balises pas faciles a nettoyer...

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...