Java Bandingkan Dua Daftar


92

Saya punya dua daftar (bukan daftar java, Anda bisa mengatakan dua kolom)

Sebagai contoh

**List 1**            **Lists 2**
  milan                 hafil
  dingo                 iga
  iga                   dingo
  elpha                 binga
  hafil                 mike
  meat                  dingo
  milan
  elpha
  meat
  iga                   
  neeta.peeta    

Saya ingin metode yang mengembalikan berapa banyak elemen yang sama. Untuk contoh ini seharusnya 3 dan harus mengembalikan nilai yang sama dari daftar dan nilai yang berbeda juga.

Haruskah saya menggunakan hashmap jika ya lalu metode apa untuk mendapatkan hasil saya?

Tolong bantu

PS: Itu bukan tugas sekolah :) Jadi kalau dibimbing saja sudah cukup


Tolong sarankan struktur data apa pun. Daftar ini bukan daftar java atau hashmap atau struktur data apa pun
pengguna238384

1
Pastikan untuk memikirkan tentang apa yang harus Anda lakukan dalam kasus luar biasa. Bisakah daftar berisi nilai yang sama dua kali? Jika demikian, jika "dingo" ada di kedua daftar dua kali, apakah itu dihitung sebagai dua elemen yang sama atau hanya satu?
JavadocMD

Bisakah Anda mengubah salah satu Daftar?
Anthony Forloney

bagaimana cara mengedit ?? Ya, setiap daftar dapat berisi nilai yang sama beberapa kali
pengguna238384

Harus ada tautan edit kecil tepat setelah pertanyaan, di bawah tag.
OscarRyz

Jawaban:


159

EDIT

Ini adalah dua versi. Satu penggunaan ArrayListdan penggunaan lainnyaHashSet

Bandingkan mereka dan buat versi Anda sendiri dari ini, sampai Anda mendapatkan yang Anda butuhkan.

Ini seharusnya cukup untuk menutupi:

PS: Itu bukan tugas sekolah :) Jadi kalau dibimbing saja sudah cukup

bagian dari pertanyaan Anda.

melanjutkan dengan jawaban asli:

Anda dapat menggunakan a java.util.Collection dan / atau java.util.ArrayListuntuk itu.

The retainAll Metode melakukan berikut ini:

Mempertahankan hanya elemen dalam koleksi ini yang terdapat dalam koleksi yang ditentukan

lihat contoh ini:

import java.util.Collection;
import java.util.ArrayList;
import java.util.Arrays;

public class Repeated {
    public static void main( String  [] args ) {
        Collection listOne = new ArrayList(Arrays.asList("milan","dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta"));
        Collection listTwo = new ArrayList(Arrays.asList("hafil", "iga", "binga", "mike", "dingo"));

        listOne.retainAll( listTwo );
        System.out.println( listOne );
    }
}

EDIT

Untuk bagian kedua (nilai serupa) Anda dapat menggunakan metode removeAll :

Menghapus semua elemen koleksi ini yang juga terdapat dalam koleksi yang ditentukan.

Versi kedua ini memberi Anda juga nilai yang serupa dan pegangan yang berulang (dengan membuangnya).

Kali ini Collectionbisa menjadi Setbukan a List(perbedaannya adalah, Set tidak mengizinkan nilai berulang)

import java.util.Collection;
import java.util.HashSet;
import java.util.Arrays;

class Repeated {
      public static void main( String  [] args ) {

          Collection<String> listOne = Arrays.asList("milan","iga",
                                                    "dingo","iga",
                                                    "elpha","iga",
                                                    "hafil","iga",
                                                    "meat","iga", 
                                                    "neeta.peeta","iga");

          Collection<String> listTwo = Arrays.asList("hafil",
                                                     "iga",
                                                     "binga", 
                                                     "mike", 
                                                     "dingo","dingo","dingo");

          Collection<String> similar = new HashSet<String>( listOne );
          Collection<String> different = new HashSet<String>();
          different.addAll( listOne );
          different.addAll( listTwo );

          similar.retainAll( listTwo );
          different.removeAll( similar );

          System.out.printf("One:%s%nTwo:%s%nSimilar:%s%nDifferent:%s%n", listOne, listTwo, similar, different);
      }
}

Keluaran:

$ java Repeated
One:[milan, iga, dingo, iga, elpha, iga, hafil, iga, meat, iga, neeta.peeta, iga]

Two:[hafil, iga, binga, mike, dingo, dingo, dingo]

Similar:[dingo, iga, hafil]

Different:[mike, binga, milan, meat, elpha, neeta.peeta]

Jika tidak melakukan apa yang Anda butuhkan, itu memberi Anda awal yang baik sehingga Anda dapat menangani dari sini.

Pertanyaan untuk pembaca: Bagaimana Anda akan memasukkan semua nilai yang diulang?


@Oscar, Saya benar-benar berpikir, tetapi saya tidak yakin apakah kami dapat mengubah konten listOne, tetapi tetap memberi +1!
Anthony Forloney

@poygenelubricants apa yang Anda maksud dengan jenis mentah bukan obat generik? Kenapa tidak?
OscarRyz

Oscar, apakah Anda melihat pertanyaan terbaru saya? Apakah itu mendukung nilai berulang?
pengguna238384

@Oscar: java.sun.com/docs/books/jls/third_edition/html/… "Penggunaan tipe mentah dalam kode yang ditulis setelah pengenalan genericity ke dalam bahasa pemrograman Java sangat tidak disarankan. Ada kemungkinan bahwa versi masa depan bahasa pemrograman Java akan melarang penggunaan jenis mentah. "
poligenelubricants

2
Jawaban @polygenelubricants diperbarui untuk menangani duplikat dan jenis mentah. BTW, versi .. Java yang akan datang ... tidak akan pernah terjadi. ;)
OscarRyz


9

Apakah ini benar-benar daftar (diurutkan, dengan duplikat), atau apakah mereka set (tidak berurutan, tidak ada duplikat)?

Karena jika yang terakhir, maka Anda dapat menggunakan, katakanlah, a java.util.HashSet<E>dan melakukan ini dalam waktu linier yang diharapkan dengan menggunakan kemudahan retainAll.

    List<String> list1 = Arrays.asList(
        "milan", "milan", "iga", "dingo", "milan"
    );
    List<String> list2 = Arrays.asList(
        "hafil", "milan", "dingo", "meat"
    );

    // intersection as set
    Set<String> intersect = new HashSet<String>(list1);
    intersect.retainAll(list2);
    System.out.println(intersect.size()); // prints "2"
    System.out.println(intersect); // prints "[milan, dingo]"

    // intersection/union as list
    List<String> intersectList = new ArrayList<String>();
    intersectList.addAll(list1);
    intersectList.addAll(list2);
    intersectList.retainAll(intersect);
    System.out.println(intersectList);
    // prints "[milan, milan, dingo, milan, milan, dingo]"

    // original lists are structurally unmodified
    System.out.println(list1); // prints "[milan, milan, iga, dingo, milan]"
    System.out.println(list2); // prints "[hafil, milan, dingo, meat]"

baik saya benar-benar tidak tahu struktur data mana yang seharusnya. Ini memiliki duplikat. Sekarang Anda dapat melihat pertanyaan yang diperbarui
pengguna238384

Apakah ini akan menghapus nilai berulang dari kumpulan data? karena saya tidak ingin kehilangan nilai apa pun :(
user238384

@agazerboy: Saya telah mencoba menjawab kedua pertanyaan tersebut. Jangan ragu untuk meminta klarifikasi lebih lanjut.
poligenelubricants

terima kasih poli. Saya mencoba program Anda dengan duplikat misalnya di daftar pertama saya menambahkan "iga" dua kali tetapi tetap mengembalikan saya 3 sebagai jawaban. Padahal seharusnya 4 sekarang. karena daftar 1 memiliki 4 nilai yang sama. Jika saya menambahkan satu entri beberapa kali seharusnya berfungsi. Apa yang kamu katakan? Ada struktur data lain?
pengguna238384

6

Menggunakan java 8 removeIf

public int getSimilarItems(){
    List<String> one = Arrays.asList("milan", "dingo", "elpha", "hafil", "meat", "iga", "neeta.peeta");
    List<String> two = new ArrayList<>(Arrays.asList("hafil", "iga", "binga", "mike", "dingo")); //Cannot remove directly from array backed collection
    int initial = two.size();

    two.removeIf(one::contains);
    return initial - two.size();
}

Kelihatannya bagus, tetapi jika saya ingin agar daftar tidak diubah, saya harus mengkloning salah satu daftar dan itu tidak akan diinginkan dalam kasus tertentu.
Sebastian D'Agostino

6

Jika Anda mencari cara praktis untuk menguji persamaan dua koleksi, Anda dapat menggunakan org.apache.commons.collections.CollectionUtils.isEqualCollection, yang membandingkan dua koleksi terlepas dari urutannya.


4

Dari semua pendekatan, menurut saya menggunakan org.apache.commons.collections.CollectionUtils#isEqualCollectionadalah pendekatan terbaik. Inilah alasannya -

  • Saya tidak perlu mendeklarasikan daftar tambahan / menetapkan sendiri
  • Saya tidak mengubah daftar input
  • Sangat efisien. Ia memeriksa kesetaraan dalam kompleksitas O (N).

Jika tidak memungkinkan untuk memiliki apache.commons.collectionsketergantungan, saya akan merekomendasikan untuk menerapkan algoritme berikut ini untuk memeriksa kesetaraan daftar karena efisiensinya.


3

Solusi sederhana: -

    List<String> list = new ArrayList<String>(Arrays.asList("a", "b", "d", "c"));
    List<String> list2 = new ArrayList<String>(Arrays.asList("b", "f", "c"));

    list.retainAll(list2);
    list2.removeAll(list);
    System.out.println("similiar " + list);
    System.out.println("different " + list2);

Keluaran: -

similiar [b, c]
different [f]

1

Dengan asumsi hash1danhash2

List< String > sames = whatever
List< String > diffs = whatever

int count = 0;
for( String key : hash1.keySet() )
{
   if( hash2.containsKey( key ) ) 
   {
      sames.add( key );
   }
   else
   {
      diffs.add( key );
   }
}

//sames.size() contains the number of similar elements.

Dia menginginkan daftar kunci yang identik, bukan berapa banyak kunci yang identik. Kupikir.
Rosdi Kasim

Terima kasih Stefan atas bantuan Anda. Ya Rosdi benar dan Anda juga. Saya membutuhkan jumlah total nilai yang sama dan nilai yang serupa juga.
pengguna238384

1

Saya menemukan contoh yang sangat mendasar dari Perbandingan daftar di Perbandingan Daftar Contoh ini memverifikasi ukuran terlebih dahulu dan kemudian memeriksa ketersediaan elemen tertentu dari satu daftar di daftar lainnya.


-1
public static boolean compareList(List ls1, List ls2){
    return ls1.containsAll(ls2) && ls1.size() == ls2.size() ? true :false;
     }

public static void main(String[] args) {

    ArrayList<String> one = new ArrayList<String>();
    one.add("one");
    one.add("two");
    one.add("six");

    ArrayList<String> two = new ArrayList<String>();
    two.add("one");
    two.add("six");
    two.add("two");

    System.out.println("Output1 :: " + compareList(one, two));

    two.add("ten");

    System.out.println("Output2 :: " + compareList(one, two));
  }

1
Solusi ini mengembalikan hasil yang salah ketika dua berisi 3 salinan "satu". Itu akan salah menghasilkan hasil yang benar.
Joseph Fitzgerald

Terima kasih untuk bagian ini: && ls1.size () == ls2.size ()
Nouar

1
Adakah alasan yang menurut Anda ? true :falsediperlukan dalam cuplikan Anda?
Krzysztof Tomaszewski
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.