Creer un tableaux de grande taille de type int

Résolu/Fermé
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 - Modifié par neocol le 12/03/2014 à 23:29
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 - 19 mars 2014 à 00:09
Bonjour,

Comment créer un tableau de large taille des int, exemple :

int[] Tab = new Tab[1000000]; un tableau qui contient un million d'élément de type int.
Eclipse Kepler, n'accepte pas ce grand nombre d'éléments

Merci d'avance,
All the Best,
Youness

5 réponses

tarek_dotzero Messages postés 817 Date d'inscription jeudi 19 juillet 2007 Statut Membre Dernière intervention 12 avril 2022 120
13 mars 2014 à 02:58
Bonjour,

Vous pouvez utiliser un tableau dynamique, c'est mieux.

ArrayList disponible dans le package java.util.* peut vous aider, il vous permet d'ajouter des objets d'une façon presque illimitée et tout moment vous pouvez accéder une utilisant l'indice exactement comme les tableaux.

https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html

Il reste une petite remarque, ArrayList ne predn que des objets alors pour insérer des entier vous devez passer par l'objet Integer (au lieu de int).

https://docs.oracle.com/javase/7/docs/api/java/lang/Integer.html

Bon Courage.
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
13 mars 2014 à 03:00
Merci bien pour ton aide tarek.
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
Modifié par neocol le 13/03/2014 à 03:58
Salut, j'ai une question si vous permettez,

J'ai créé une fonction qui retourne une Arraylist AR.cette fonction marche dans une boucle.
comment faire pour que la nouvelle AR soit ajoutée à la fin de l'ancienne AR ?
j'ai essayé deux boucles :
MaListArray (de type String) = calculate(int n);
System.out.println("MaListArray="+MaListArray);
1ére méthode
for (String st1 : MaListArray)
{
//int i;
st1=MaListArray.get(i);
System.out.println("st1"+st1);
MaListArray.add(st1);
}
System.out.println("MaListArray apres update"+MaListArray);
2émé méthode
for(int i=0; i<MaListArray.size(); i++)
{
st1 = MaListArray.get(i);
// System.out.println("st1"+st1);
MaListArray.add(str1);
}
System.out.println("MaListArray apres update"+MaListArray);

Mais dans les deuc cas : il me dit Unknown source , pourtant :
System.out.println("MaListArray="+MaListArray); donne le bon résultat

Merci
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 998
13 mars 2014 à 07:45
Si Eclipse n'accepte pas
int[] Tab = new Tab[1000000];
ce n'est pas parce qu'il y a 1 million d'éléments, mais parce que c'est un tableau d'entier que tu veux et tu lui construis un tableau de Tab !!! Il faudrait écrire
int[] Tab = new int[1000000];
.

Remarque : une ArrayList est construite en interne à partir d'un tableau aussi. Si la liste contient 1 million d'éléments tu auras un tableau interne de taille 1 million ou plus. Sauf que ce sera de Integer qui sont beaucoup plus coûteux en mémoire que des int (environ 5 fois plus gros).
De plus, par défaut, le tableau d'un
new ArrayList<Integer>()
ne contient que 10 éléments, au 11è élément ajouté tout sera copié dans un tableau de taille 20, au 21è tout est copié dans un tableau de taille 40, etc. jusqu'à 1 million. Ça va faire beaucoup de copies inutiles. Si tu sais à l'avance que ta liste contiendra 1 millions d'éléments, il faut lui préciser en paramètre du constructeur
new ArrayList<Integer>(1_000_000);
ce qui initialiseras directement le tableau à la bonne taille... comme quoi ce n'est pas la taille qui lui pose problème. La taille maximale (théorique) d'un tableau c'est Integer.MAX_VALUE, mais tu auras certainement des problèmes de mémoire avant.
0
ElementW Messages postés 4764 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021 1 293
Modifié par gravgun le 13/03/2014 à 09:32
Edit: je sais pas lire les chiffres. Trois zéros en plus ça fait mal
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 998 > ElementW Messages postés 4764 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021
13 mars 2014 à 09:29
4 000 000 d'octets ça fait 4 Mo, pas 4 Go...
0
ElementW Messages postés 4764 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021 1 293
13 mars 2014 à 09:31
Oups :/
J'sais plus lire moi...
Bon n'empêche que je doute que la JVM accepte un tel tableau avec ses paramètres par défaut.
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 998 > ElementW Messages postés 4764 Date d'inscription dimanche 12 juin 2011 Statut Contributeur Dernière intervention 5 octobre 2021
13 mars 2014 à 12:35
C'est pour ça que j'indiquais que Integer.MAX_VALUE (qui est la taille maximale d'un tableau) poserait un problème de mémoire. Ça ferait 8Go pour un int[]... mais sur un serveur bien configuré ça passerait. Il faudrait cependant se poser de grosses questions d'optimisation ^^
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
Modifié par neocol le 16/03/2014 à 20:17
Bonjour,

Ce que je veux faire avec un tel tableau, c'est que je dois écrire dans un fichier.txt des lignes de 0 et 1.

Mon tableau est de la forme : tab[int i1][int i2]; du coup je dois travailler sur un grand nombre de lignes.

je peux écrire long i1,i2;
mais eclipse n'accepte pas long tab[long i1][long i2]; ça répond que i1 et i2 doivent être des int.
exactement cette erreur : " java.lang.OutOfMemoryError: Java heap space" lorsque je fais tab[1000000][200].

Mon but, c'est avoir ces nombres i1,i2 aléatoire pour pouvoir générer une matrice des 0 et 1, et ensuite les écrire dans un fichier ?

Est-ce-qu'il y a une manière pour dire d'accepter des fichiers de grandes tailles? et donc pouvoir créer des tableau de grande taille, par exemple : tab[1000000][500] , ceux sont les nombres que je veux atteindre.

Je travaille actuellement, sur un tab[10000][200], mais je veux plus, car je dois travailler sur des transactions des grands supermarchés.

Merci pour votre aide.

All the Best,
Youness
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 998
16 mars 2014 à 20:27
"je peux écrire long i1,i2; mais eclipse n'accepte pas long tab[long i1][long i2];"
Déjà ce n'est pas Eclipse qui veut pas, mais c'est le langage Java qui définit ça comme ça.
De toute façon si tu mettais des long, ça voudrait dire que tu pourrais dépasser la valeur Integer.MAX_VALUE ce qui ferait planter la mémoire car ton tableau se compterait en Go !!

"avoir ces nombres i1,i2 aléatoire pour pouvoir générer une matrice des 0 et 1, et ensuite les écrire dans un fichier"
Est il vraiment nécessaire de générer la totalité de la matrice en mémoire avant de l'écrire dans le fichier ? Tu gagnerais beaucoup à traiter ton fichier au fur et à mesure.

"des lignes de 0 et 1"
Alors pourquoi utiliser des int, qui font 4 octets, alors que tu pourrais utiliser des byte, qui font 1 octet, voir même stocker 8 valeurs 0/1 dans un seul byte. En réfléchissant un peu sur le type de ton tableau tu peux donc diviser ta consommation mémoire par 32 !

tab[1000000][500] , ceux sont les nombres que je veux atteindre.
1 000 000 * 500 / 8 / 1024² = 60 Mo... Java est capable de supporter 60 Mo de mémoire !
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
16 mars 2014 à 20:37
Merci, je vais me renseigner sur le type Byte.

J'ai pas bien compris ta phrase :
"Est il vraiment nécessaire de générer la totalité de la matrice en mémoire avant de l'écrire dans le fichier ? Tu gagnerais beaucoup à traiter ton fichier au fur et à mesure.
"
ce que je fais ,
tab[i1][i2] = valeurMin+ r.nextInt(valeurMax - valeurMin); // valmin =0 et valmax=2
MyFile.write(tab[i1][i2]);

Est-ce-qu'il y a une autre façon de le faire ?

Merci,
Youness
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 998
16 mars 2014 à 20:43
Dans la mesure où tes valeurs sont aléatoires, et donc qu'il n'y a aucun lien entre le 1ère et la deuxième case, pas plus qu'avec la 3è ou la 4è, il n'y a donc encore moins d'intérêt à conserver les 500 millions de valeurs de ton tableau, alors qu'il n'y en a qu'une qui t'intéresse à chaque fois.

Tu peux donc tout à fait, choisir un nombre aléatoire, l'écrire dans ton fichier, et passer au suivant. Le stocker dans un tableau est totalement superflue et consomme inutilement de la mémoire.

int n = valeurMin+ r.nextInt(valeurMax - valeurMin); // valmin =0 et valmax=2 
MyFile.write(n); 
0
neocol Messages postés 63 Date d'inscription mardi 4 juin 2013 Statut Membre Dernière intervention 6 février 2016 1
16 mars 2014 à 21:20
J'ai essayé votre méthode, mais je reçois toujours l'erreur de la mémoire, voilà ce que j'ai fait :
Scanner sc = new Scanner(System.in);
System.out.println("Nombre de transactions? :");
long num1 = sc.nextLong();
System.out.println("\n Nombre d'items? :");
long num2 = sc.nextLong();
byte valeurMin = 0;
byte valeurMax = 2;
long i, j = 0;
Random r = new Random();
for (i = 0; i < num1; i++) {
for (j = 0; j < num2; j++) {
byte valeur = (byte) (valeurMin + r.nextInt(valeurMax - valeurMin));
file_out.write(valeur + " "); /// je veux séparer les 0 et 1 par espace
}
file_out.write("\n"); // a chaque transaction je dois retourner à la ligne suivante
}
file_out.close();


Ca se passe bien pour num1=10 000 et num2=200
mais pour num1=1 000 000 et num2=200 : "java.lang.OutOfMemoryError: Java heap space"
je reçois cette erreur.

J'ai enlevé le tableau Tab[num1][num2]=valeur;

Si vous avez une autre vue, j'en serai bien respectueux.

Merci,
Youness
0
KX Messages postés 16664 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 21 janvier 2023 2 998
16 mars 2014 à 21:48
"J'ai enlevé le tableau Tab[num1][num2]=valeur;"
Evidemment qu'il faut enlever le tableau, il ne te sers à rien !

Et sans le tableau tu ne devrais plus avoir d'erreur de mémoire...

Remarque : vu que tu n'as plus de tableau, que ce soit un byte ou un int ça ne change plus grand chose, mais si c'est effectivement 0 ou 1 que tu veux, tu peux faire un nextBoolean avec le Random.

Autre chose, avoir un long ne sert à rien dans une boucle, les int suffisent largement, de toute façon comme je l'ai déjà dit et redis, si tu dépassait Integer.MAX_VALUE tu serais avec des valeurs en Go, alors c'est moins grave pour un fichier, d'autant qu'on peut le zipper en live avec Java, mais ça veut dire que ton programme va tourner pendant très longtemps pour te générer des Go de 0 et 1 sans intérêts... alors si un jour tu as vraiment besoin de long, il faudra repenser le programme, mais en attendant les int suffiront largement !

Rappel : Integer.MAX_VALUE = 2^31-1, donc 2 milliards de transactions, avec 2 milliards d'items ça fait 4 milliards de milliards de 0 et 1, soit 4 Eo de données... oublies les long, ça servira jamais !

Scanner sc = new Scanner(System.in);

System.out.print("Nombre de transactions : ");
int nbRow = sc.nextInt();

System.out.println("Nombre d'items : ");
int nbCol = sc.nextInt();

for (int row = 0; row < nbRow; row++)
{ 
    for (int col = 0; j < nbCol; col++)
    {
        if (r.nextBoolean())
            fileOut.write("0 ");
        else
            fileOut.write("1 ");
    }
    
    fileOut.write("\n");
}

Attention par contre à bien choisir le type de fileOut, parce que la vitesse du programme va beaucoup dépendre de ça vu que tu vas faire des centaines de millions d'écriture sur le fichiers il vaut mieux que ce soit bufferisé.
0