Hoe een array "verkleinen" - Java

Dus stel dat ik een array maak met 5 spaties, zoals so - String [] myArray = new String [5] . Stel dat ik een aantal van die items definieer, maar laat een aantal van hen null (of wat dan ook de Java-term is voor een ongedefinieerd array-item/variabele), zoals:

myArray[0] = "foo";
myArray[2] = "bar";
myArray[4] = "foobar";

Is er een manier om die array te "verkleinen", alle null-items eruit te persen (de grootte ervan niet wijzigen)? Zodat de index van "foo" op 0 blijft, maar "bar" index 1 wordt, en "foobar" zich op 2 bevindt, met de laatste 2 spaties leeg? Lang verhaal kort - schuifelen rond de items in een array, alle nul-items naar het einde duwen, met behoud van de relatieve volgorde van de andere items. Is daar al een vooraf gedefinieerde Java-methode voor, of moet ik die zelf maken?

4

6 antwoord

U kunt de volgende aanpak gebruiken ( zonder overhead van instantie Collections ):

import java.util.Arrays;

public class ArraySample {

    public static void main(final String[] args) {
        String[] src = new String[] { "foo", null, "bar", null, "foobar" };
        String[] dest = new String[src.length];

        int i = 0;
        for (String s : src) {
            if (s != null) {
                dest[i++] = s;
            }
        }

        System.out.println(Arrays.toString(src));
        System.out.println(Arrays.toString(dest));
    }

}
5
toegevoegd
Heb ik mijn belangrijkste methode nodig om die uitzonderingen te gooien?
toegevoegd de auteur Bluefire, de bron
Oh: O, dus ik heb de invoer van java.io. * niet nodig, denk ik?
toegevoegd de auteur Bluefire, de bron
@Bluefire: bedankt!
toegevoegd de auteur Francisco Spaeth, de bron
@Spaeth U kunt het doen zonder een andere array te maken.
toegevoegd de auteur alain.janinm, de bron

U kunt dit doen met alleen de bronarray:

    String[] src = new String[] { "foo", "foo3", null,null, "bar", null,null, "foobar", "foo2", null,"foo5",null };
    int lastNullIdx = -1;

    for (int i=0; i 
5
toegevoegd

Met functionaljava ,

array(myArray).filter(new F() {
  public Boolean f(String s) { 
    return s != null; 
  }
});

Dit zal de elementen behouden die aan de gegeven voorwaarden voldoen. Het resultaat is de nieuwe array geretourneerd door filter .

Bewerken

Sorry, ik heb de vraag eerder verkeerd gelezen. Hier leest u hoe u null s naar rechts eruit kunt persen.

array(myArray).sort(
  booleanOrd.comap(new F() {
    public Boolean f(String s) {
      return s == null;
    }
  })
);
1
toegevoegd
Rechts. Functionjava is echter completer met betrekking tot functionele programmeringsabstracties.
toegevoegd de auteur missingfaktor, de bron
Sorry, ik heb de vraag eerder verkeerd gelezen. En bedankt voor het verwijzen naar dat! Ik heb mijn antwoord dienovereenkomstig bewerkt.
toegevoegd de auteur missingfaktor, de bron
coole aanpak! dezelfde aanpak kan worden verkregen door Commons Collections te gebruiken door Collections.filter
toegevoegd de auteur Francisco Spaeth, de bron
maar ik vraag me af in deze zaak dat je de nulelementen eruit filtert toch? En de bedoeling was om dezelfde array-grootte te presenteren door alleen de niet-nulelementen naar links te verschuiven ...
toegevoegd de auteur Francisco Spaeth, de bron
nog steeds een goed antwoord!
toegevoegd de auteur Francisco Spaeth, de bron

Plaatselijke verkorting, eenvoudigere code:

public static String[] minify(String[] x) {
  int d = 0;
  for (String s : x) if (s != null) x[d++] = s;
  while (d < x.length) x[d++] = null;
  return x;
}

public static void main(String[] args) {
  System.out.println(Arrays.toString(
      minify(new String[] {"foo", null, "bar", null, "foobar"})));
}
1
toegevoegd

Denk niet dat er een methode voor is. Als er zoiets zou zijn, zou dat in java.util.Arrays zijn. Ik zou het zo doen

String[] src = new String[] { "foo", null, "bar", null, "foobar" };

for (int c = 0, j = 0; c < src.length; c++) {
    if (src[c] != null) {
        src[j++] = src[c];
        src[c] = null;
    }
}

Bewerk:

String[] src = new String[] { "foo", null, "bar", null, "foobar" };
Comparator NEW_ORDER = new Comparator() {
    public int compare(String e1, String e2) {
        if(e1 == null)return 1;
        if(e2 == null)return -1;
        return 0;
    }
Arrays.sort(src, NEW_ORDER);

Zou ook moeten werken, omdat Arrays.sort een stabiele sortering is, maar ik denk dat de andere oplossing beter is, omdat zijn O (n) en niet O (n log n)

1
toegevoegd
De eerste oplossing is al een schoonheid, geen behoefte aan de tweede :)
toegevoegd de auteur Marko Topolnik, de bron

Java is al voorbereid op een dergelijk sorteerprobleem met behulp van de Arrays.sort (T [] a, Comparator c) methode:

Arrays.sort(myArray, new StringNullComparator());

met

class StringNullComparator implements Comparator {

    @Override
    public int compare(String s1, String s2)
    {
        if(s1==null && s2!=null) return 1;
        else if(s1!=null && s2==null) return -1;
        else return 0;
    }
}

Op deze manier kunt u zelfs de nulwaarden sorteren op lagere indecees door de waarde die wordt geretourneerd door de vergelijkingsmethode om te keren.

0
toegevoegd