Yineleyici olmadan bir Set / HashSet üzerinden yineleme nasıl yapılır?


273

Aşağıdakiler olmadan Set/ HashSetolmadan nasıl yineleyebilirim ?

Iterator iter = set.iterator();
while (iter.hasNext()) {
    System.out.println(iter.next());
}

31
Bir yineleyicinin kullanımından kaçınmaya mı çalışıyorsunuz, yoksa sadece kaynak kodunuzda görmek istemiyor musunuz?
Jon Skeet

2
Kodu daha kısa ve daha temiz hale getirebilirsiniz, ancak bir Yineleyici kullanmanız gerekir. Bundan kaçınmak için bir neden var mı?
Peter Lawrey

5
Sadece rekor ve neden yineleyici önlemek için açıklama olarak: Şu anda Java ile yazılmış bir Android oyunu bu sorunla karşı karşıya. Şu anda, etkinlikler hakkında düzenli olarak bilgilendirilmesi gereken dinleyicileri saklamak için bir HashSet kullanıyorum. Bununla birlikte, koleksiyonları tekrar tekrar yinelemek, oyun döngüsünü yükleyebilecek ağır çöp toplayıcı etkinliğine neden olur. Ve bu bir Java oyununda bir hareketsizlik. Bu parçaları yeniden yazacağım.
tiguchi

12
@thecoshman Sadece her ne pahasına olursa olsun düzenli oyun durumu güncellemeleri sırasında GC'den kaçınmak istediğiniz bir Java oyun geliştirme perspektifinden konuşuyorum. Yineleyiciler yalnızca geçici olarak yararlı nesnelerdir, çünkü onları başlangıç ​​noktasına sıfırlayamazsınız, bu nedenle her yineleme yöntemi çağrısında yeniden oluşturulurlar (örneğin, bkz. ArrayList.java kaynağı). Sahne nesnelerini yinelemek ve saniyede en az 30 güncellemeyi göz önünde bulundurmak için bir oyun döngüsünde kullanılırsa, GC için bekleyen bellekte saniyede en az 60 (sahne genellikle döngü başına iki kez yinelenir) yineleyici nesneleri elde edersiniz. Bunun Android üzerinde büyük bir etkisi var.
tiguchi

9
Belki de bu durumda daha uygun bir veri yapısı seçilmelidir? Bir set verimli bir şekilde tekrarlamak için tasarlanmamıştır. Neden bir ArrayList kullanmıyorsunuz ve döngü için bir standart ile tekrar ediyorsunuz? Ek yineleyiciler oluşturulmaz, okuma erişimi çok hızlıdır.
stef77

Yanıtlar:


492

Geliştirilmiş bir döngü için kullanabilirsiniz :

Set<String> set = new HashSet<String>();

//populate set

for (String s : set) {
    System.out.println(s);
}

Veya Java 8 ile:

set.forEach(System.out::println);

65
Bunun perde arkasında bir yineleyici kullandığına inanıyorum.
munyengm

22
@munyengm Evet öyle. Yansıma yoluyla verileri tutan temel yapıya erişmek ve Set # iterator tarafından sağlanan kodu çoğaltmak dışında, bir yineleyici olmayan bir set üzerinde tekrarlamanın bir yolu yoktur ...
assylias

1
Bu işe yarıyor, ancak sorun çıkarsa, bu benim için bir çözüm değil. Sanırım başka seçeneğim yok, Iterator kullanmalıyım. Yine de herkese teşekkürler.
user1621988

39
@ user1621988 Ne sorunları? Sağladığım kodla ilgili bir sorun yok. Açıkça bir yineleyici kullanmak zorunda kalmadan bir set üzerinde yineleme yapmak için güzel ve temiz bir yol sağlar.
assylias

90

Bir set üzerinde yinelemenin en az altı ek yolu vardır. Aşağıdakiler beni tanıyor:

Yöntem 1

// Obsolete Collection
Enumeration e = new Vector(movies).elements();
while (e.hasMoreElements()) {
  System.out.println(e.nextElement());
}

Yöntem 2

for (String movie : movies) {
  System.out.println(movie);
}

Yöntem 3

String[] movieArray = movies.toArray(new String[movies.size()]);
for (int i = 0; i < movieArray.length; i++) {
  System.out.println(movieArray[i]);
}

Yöntem 4

// Supported in Java 8 and above
movies.stream().forEach((movie) -> {
  System.out.println(movie);
});

Yöntem 5

// Supported in Java 8 and above
movies.stream().forEach(movie -> System.out.println(movie));

Yöntem 6

// Supported in Java 8 and above
movies.stream().forEach(System.out::println);

Bu HashSetbenim örnekler için kullanılan hangi:

Set<String> movies = new HashSet<>();
movies.add("Avatar");
movies.add("The Lord of the Rings");
movies.add("Titanic");

10
Hi @ benny-neugebauer Yöntem 4 , Yöntem 5 , Yöntem 6 için artıklığı kaldırabilirsiniz stream().
Eugene T

5
Yöntem 4, Yöntem 5 ve Yöntem 6'nın aynı olduğunu belirtmiyoruz.
GustavoCinque

24

Setinizi bir diziye dönüştürmek , öğeler üzerinde yineleme yapmanıza da yardımcı olabilir:

Object[] array = set.toArray();

for(int i=0; i<array.length; i++)
   Object o = array[i];

45
Sadece kayıt toArrayiçin setin yineleyicisini çağırır.
assylias

13

Göstermek için, farklı Kişi nesnelerini içeren aşağıdaki seti göz önünde bulundurun:

Set<Person> people = new HashSet<Person>();
people.add(new Person("Tharindu", 10));
people.add(new Person("Martin", 20));
people.add(new Person("Fowler", 30));

Kişi Modeli Sınıfı

public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    //TODO - getters,setters ,overridden toString & compareTo methods

}
  1. For ifadesi, Koleksiyonlar ve diziler aracılığıyla yineleme için tasarlanmış bir forma sahiptir.
for(Person p:people){
  System.out.println(p.getName());
}
  1. Java 8 - java.lang.Iterable.forEach (Tüketici)
people.forEach(p -> System.out.println(p.getName()));
default void forEach(Consumer<? super T> action)

Performs the given action for each element of the Iterable until all elements have been processed or the action throws an exception. Unless otherwise specified by the implementing class, actions are performed in the order of iteration (if an iteration order is specified). Exceptions thrown by the action are relayed to the caller. Implementation Requirements:

The default implementation behaves as if: 

for (T t : this)
     action.accept(t);

Parameters: action - The action to be performed for each element

Throws: NullPointerException - if the specified action is null

Since: 1.8

11

Daha düzgün bir kod için işlevsel işlemi kullanabilirsiniz

Set<String> set = new HashSet<String>();

set.forEach((s) -> {
     System.out.println(s);
});

Çağrı API 24 gerektirir
djdance

11

Performanslarıyla birlikte bir Setin nasıl tekrarlanacağıyla ilgili birkaç ipucu:

public class IterateSet {

    public static void main(String[] args) {

        //example Set
        Set<String> set = new HashSet<>();

        set.add("Jack");
        set.add("John");
        set.add("Joe");
        set.add("Josh");

        long startTime = System.nanoTime();
        long endTime = System.nanoTime();

        //using iterator
        System.out.println("Using Iterator");
        startTime = System.nanoTime();
        Iterator<String> setIterator = set.iterator();
        while(setIterator.hasNext()){
            System.out.println(setIterator.next());
        }
        endTime = System.nanoTime();
        long durationIterator = (endTime - startTime);


        //using lambda
        System.out.println("Using Lambda");
        startTime = System.nanoTime();
        set.forEach((s) -> System.out.println(s));
        endTime = System.nanoTime();
        long durationLambda = (endTime - startTime);


        //using Stream API
        System.out.println("Using Stream API");
        startTime = System.nanoTime();
        set.stream().forEach((s) -> System.out.println(s));
        endTime = System.nanoTime();
        long durationStreamAPI = (endTime - startTime);


        //using Split Iterator (not recommended)
        System.out.println("Using Split Iterator");
        startTime = System.nanoTime();
        Spliterator<String> splitIterator = set.spliterator();
        splitIterator.forEachRemaining((s) -> System.out.println(s));
        endTime = System.nanoTime();
        long durationSplitIterator = (endTime - startTime);


        //time calculations
        System.out.println("Iterator Duration:" + durationIterator);
        System.out.println("Lamda Duration:" + durationLambda);
        System.out.println("Stream API:" + durationStreamAPI);
        System.out.println("Split Iterator:"+ durationSplitIterator);
    }
}

Kod kendi kendini açıklamaktadır.

Sürelerin sonucu:

Iterator Duration: 495287
Lambda Duration: 50207470
Stream Api:       2427392
Split Iterator:    567294

LambdaEn uzun sürenin Iteratoren hızlı olduğunu görüyoruz .


2

Sayım (?):

Enumeration e = new Vector(set).elements();
while (e.hasMoreElements())
    {
        System.out.println(e.nextElement());
    }

Başka bir yol (java.util.Collections.enumeration ()):

for (Enumeration e1 = Collections.enumeration(set); e1.hasMoreElements();)
    {
        System.out.println(e1.nextElement());
    }

Java 8:

set.forEach(element -> System.out.println(element));

veya

set.stream().forEach((elem) -> {
    System.out.println(elem);
});

0

Ancak bunun için çok iyi cevaplar var. İşte cevabım:

1. set.stream().forEach(System.out::println); // It simply uses stream to display set values
2. set.forEach(System.out::println); // It uses Enhanced forEach to display set values

Ayrıca, bu Set Özel sınıf türündeyse, örneğin: Müşteri.

Set<Customer> setCust = new HashSet<>();
    Customer c1 = new Customer(1, "Hena", 20);
    Customer c2 = new Customer(2, "Meena", 24);
    Customer c3 = new Customer(3, "Rahul", 30);

setCust.add(c1);
setCust.add(c2);
setCust.add(c3);
    setCust.forEach((k) -> System.out.println(k.getId()+" "+k.getName()+" "+k.getAge()));

// Müşteri sınıfı:

class Customer{
private int id;
private String name;
private int age;

public Customer(int id,String name,int age){
this.id=id;
this.name=name;
this.age=age;
} // Getter, Setter methods are present.}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.