Anonyme Klasse einer Liste erstellen

ocsme

Top Contributor
Hallo,

ich versuche eine Liste als Anonyme Klasse zu instanziieren doch das klappt leider nicht!
Wieso ich das machen möchte ist weil ich dann eine Aufgabe vereinfacht bekomme 😀 vielleicht erschwere ich mir das ganze auch wieder 😛

Also hier erst einmal das was ich bis jetzt versucht habe.

Java:
List<T> a = new ArrayList<T>() {
                int k = 0;
                public void permute(int k) {
                     for(int i = k; i < data.size(); i++){
                            Collections.swap(data, i, k);
                            permute(k+1);
                            Collections.swap(data, k, i);
                        }
                        if (k == data.size() -1){
                            for(T s : data)
                                a.add((T) s.toString());
                            
                        }
                }
                permute(k);

            };

Leider verstehe ich nicht wie ich permute(k) richtig aufgerufen bekomme 🙁
Denn ich würde sehr gerne ein Array erstellen mit Permutationen. Die Daten kommen aus einem Array data. Sprich in data steht nun 1,2,3 drin dann sollte eben
1,2,3
1,3,2
2,1,3
...
raus kommen.
Doch leider verstehe ich nicht wie ich den Anfang mache damit permute sich überhaupt rührt 🙁

Vielleicht hat da jemand eine Idee 🙂

LG
 
Hierfür könntest du z.B. einen Initializer Block nehmen:
Java:
public class Permutations<T> {
  @SuppressWarnings("serial")
  public static <T> List<List<T>> createPermutations(List<T> data) {
    return new ArrayList<List<T>>() {
      {
        permute(0);
      }
      private void permute(int k) {
        for (int i = k; i < data.size(); i++) {
          Collections.swap(data, i, k);
          permute(k + 1);
          Collections.swap(data, k, i);
        }
        if (k == data.size() - 1)
          add(new ArrayList<>(data));
      }
    };
  }
  public static void main(String[] args) {
    System.out.println(Permutations.createPermutations(Arrays.asList(1, 2, 3, 4)));
  }
}
 
Danke für die Antwort.
Leider klappt es so nicht bekomme NullPointerException.
Ich erkläre mal kurz die Aufgabe vielleicht mach ich wieder alles Falsch! 🙁

Aufgabenstellung:
Die Klasse Permutator<T> stellt für eine gegebene Collection von Elementen eines beliebigen Typs T einen Iterator über alle Permutationen der Elemente, die in der Collection enthalten sind zur Verfügung.

Aufgerufen wird sie so:

public static void main(String[] args) {
for(Collections<String> c : new Permutator<String> (asList(1,2,3,4)))
System.out.print(c) }
}

Außerdem steht für Ihre Implementierung die Klasse Permutations zur Verfügung:
class Permutations implements Iterable<Iterable<Integer>> {
private int size;
public Permutations(int size) { this.size = size; }
public Iterator<Iterable<Integer>> iterator() { ... }
}

Gesucht ist Methode iterator() der Klasse Permutator<T>

Ich dachte mir, da ich mit Permutations nichts anfangen konnte, das ich im Iterator einfach die Permutation erstelle und dann gleichzeitig drüber laufe 🙂 doch das klappt leider nicht so ganz.

Code:
import java.util.*;

public class Permutator<T> {
    List<T> data;   
    Permutator() {
        
    }
    
    Permutator(List<T> t) {
        data = t;
    }

    public static void main(String[] args) {
        Permutator<String> test = new Permutator<String>(Arrays.asList("A","B","C","D"));
        
        Iterator i = test.iterator();
        while(i.hasNext())
            System.out.print(i.next()+" ");
    }

    
    public Iterator<Collection<T>> iterator() {
        return new Iterator<Collection<T>>() {
            int count = 0;
            List<T> a = new ArrayList<T>() {
                {
                    permute(0);
                }
                public void permute(int k) {
                     for(int i = k; i < data.size(); i++){
                            Collections.swap(data, i, k);
                            permute(k+1);
                            Collections.swap(data, k, i);
                        }
                        if (k == data.size() -1){
                            for(T s : data)
                                a.add((T) s.toString());
                        }
                }
            };
            
            @Override
            public boolean hasNext() {
                return count!=a.size()?true:false;
            }

            @Override
            public Collection<T> next() {
                List<T> tmp = new ArrayList<T>();
                if(hasNext()) {
                    tmp.add((T) a.get(count));
                    count++;
                }
                return tmp;
            }
            
        };
    
    }
}

LG
 
Du scheinst leider überhaupt nicht verstanden zu haben, was überhaupt die Aufgabe sein soll. Dein Iterator soll nicht einelementige Collections liefern, sondern er soll die Collections liefern, die die Permutationen der ursprünglichen Collection/Liste sind. Und wieso fügst du `s.toString()` (also .toString()) der Liste hinzu? Wieso konvertierst du denn ein `T` immer zu seiner String-Repräsentation?
Desweiteren scheinst du leider überhaupt nicht meinen Code ausprobiert zu haben. Dort steht nicht `a.add(...)` sondern `add(...)`. Du willst add() auf dem `this` Objekt direkt aufrufen, und nicht erst eine äußere Variable (dein `a`) dereferenzieren, die noch gar nicht initialisiert ist.
 
Und weil ich heute großzügig bin, hier eine mögliche Lösung (nach https://www.baeldung.com/java-array-permutations):
Java:
import java.util.*;
public class Permutator<T> implements Iterable<Collection<T>> {
  private final List<T> data;
  public Permutator(List<T> data) {
    this.data = data;
  }
  public Iterator<Collection<T>> iterator() {
    return new Iterator<Collection<T>>() {
      private final int[] indexes = new int[data.size()];
      private Collection<T> next = new ArrayList<>(data);
      private int i;
      private void advance() {
        while (next == null && i < data.size()) {
          if (indexes[i] < i) {
            Collections.swap(data, i % 2 == 0 ? 0 : indexes[i], i);
            next = new ArrayList<>(data);
            indexes[i]++;
            i = 0;
          } else {
            indexes[i] = 0;
            i++;
          }
        }
      }
      @Override
      public boolean hasNext() {
        return next != null;
      }
      @Override
      public Collection<T> next() {
        if (next == null)
          throw new NoSuchElementException();
        try {
          return next;
        } finally {
          next = null;
          advance();
        }
      }
    };
  }
  public static void main(String[] args) {
    for (Collection<String> permutation : new Permutator<String>(Arrays.asList("A", "B", "C", "D"))) {
      System.out.println(permutation);
    }
  }
}
 
Und weil ich heute großzügig bin, hier eine mögliche Lösung
Danke dafür finde ich super Nett 🙂
Werde es aber erst einmal weiter selbst Probieren.

Desweiteren scheinst du leider überhaupt nicht meinen Code ausprobiert zu haben.
Nein ausprobiert habe ich den Code nicht. Ich hab ihn überflogen und fand die Idee schon super GEIL mit dem Block also das hier:
{ Methode() }
Da dachte ich naja dann bekomme ich das auch alleine hin 😛 Falsch gedacht denn ich hatte ja nicht mehr im Kopf das die ArrayListe a so gesehen nicht existiert und dadurch auch nichts adden kann!

Du scheinst leider überhaupt nicht verstanden zu haben, was überhaupt die Aufgabe sein soll. Dein Iterator soll nicht einelementige Collections liefern, sondern er soll die Collections liefern, die die Permutationen der ursprünglichen Collection/Liste sind. Und wieso fügst du `s.toString()` (also .toString()) der Liste hinzu? Wieso konvertierst du denn ein `T` immer zu seiner String-Repräsentation?
Das alles habe ich deswegen so "hingebogen" weil meine ganze Klasse vorher anders aussah. Das ging an der Übungsaufgabe komplett vorbei aber es hat geklappt hier mal meine eigene Version von dieser Aufgabe:

Java:
import java.util.*;

public class Permutator<T> {
    
    List<T> data;
    ArrayList<T> permutation = new ArrayList<>();
    
    Permutator() {
        
    }
    
    Permutator(List<T> t) {
        data = t;
        permutation = makePermut(0);
    }
    
    public ArrayList<T> makePermut(int k){
        for(int i = k; i < data.size(); i++){
            Collections.swap(data, i, k);
            makePermut(k+1);
            Collections.swap(data, k, i);
        }
        if (k == data.size() -1){
            for(T s : data)
                permutation.add(s);
        }
        return permutation;
    }
    
    public static void main(String[] args) {
        Permutator<String> test = new Permutator<String>(Arrays.asList("A","B","C","D"));
        System.out.println(test);
        Iterator i = test.iterator();
        while(i.hasNext())
            System.out.print(i.next()+" ");
    }

    public Iterator<Collection<T>> iterator() {
        return new Iterator<Collection<T>>() {
            int count = 0;
            
            @Override
            public boolean hasNext() {
                return count!=permutation.size()?true:false;
            }

            @Override
            public Collection<T> next() {
                List<T> tmp = new ArrayList<T>();
                if(hasNext()) {
                    tmp.add((T) permutation.get(count));
                    count++;
                }
                return tmp;
            }
        };
    }
}


Erst so kam ich eben auf die Idee die Arbeit mit der Permutation (also das Array mit den Permutationen) im Iterator anzulegen 🙂

Danke nochmals 🙂

LG
 
So läuft es. Was mir gar nicht gefällt worüber ich mir jetzt aber auch nicht zwingenden den Kopf zerbrechen möchte ist die Ausgabe 😀 ich zähle den count dann einfach hoch das finde ich bei dir viel eleganter gelöst 🙂
Doch es hat letztlich auch bei mir geklappt 🙂

Nicht schön aber selten 😀
Java:
    public static void main(String[] args) {
        Permutator<String> test = new Permutator<String>(Arrays.asList("A","B","C","D"));
        Iterator i = test.iterator();
        while(i.hasNext())
            System.out.println(i.next()+" ");
    }

    public Iterator<Collection<T>> iterator() {
        return new Iterator<Collection<T>>() {
            int count = 0;
           
            ArrayList<T> a = new ArrayList<T>() {
                       {
                        permute(0);
                      }
                      private void permute(int k) {
                        for (int i = k; i < data.size(); i++) {
                          Collections.swap(data, i, k);
                          permute(k + 1);
                          Collections.swap(data, k, i);
                        }
                        if (k == data.size() - 1)
                            for(T s:data)
                                add(s);
                      }
                    };

            @Override
            public boolean hasNext() {
                return count!=a.size()?true:false;
            }

            @Override
            public Collection<T> next() {
                List<T> tmp = new ArrayList<T>();
                if(hasNext()) {
                    tmp.add((T) a.get(count));
                    count++;
                }
                return tmp;
            }
        };
    }

Bei der Ausgabe habe ich halt immer für 1 Element 1 Array 😀 wollte es so machen😀
Java:
@Override
            public Collection<T> next() {
                List<T> tmp = new ArrayList<T>();
                if(hasNext()) {
                    tmp.add((T) a.get(count++));
                    tmp.add((T) a.get(count++));
                    tmp.add((T) a.get(count++));
                    tmp.add((T) a.get(count));

                    count++;
                }
                return tmp;
            }
Das passt natürlich dann nur für 4 Elemente sind es weniger oder mehr sollte das nicht funktionieren 😀
 
Die Ausgabe mal ganz naiv runter gecodet:
Wie schon gesagt lange nicht so schön wie bei @httpdigest

Java:
@Override
            public Collection<T> next() {
                List<T> tmp = new ArrayList<T>();
//                if(hasNext()) {
//                    tmp.add((T) a.get(count));
//                    count++;
//                }
                if(hasNext()) {
                    int i = 0;
                    while(i != data.size()) {
                        tmp.add( (T) a.get(count));
                        i++;
                        count++;
                    }
                }
                
                return tmp;
            }
        };
 

Neue Themen


Zurück
Oben