Kebingungan dalam memilih struktur data

Saya ingin membuat Map<Long, Enum< ? extends SomeInterface>. Manakah pilihan terbaik bagi saya?

Saya mencoba yang ini

private Map<Long, Enum<? extends SomeInterface>[]> questionIdToanswersMapping = Collections.unmodifiableMap(Stream.of(
        new SimpleEntry<>(QuestionEnum1.getQuestionId(), AnswerEnum1.values()),
        new SimpleEntry<>(QuestionEnum2.getQuestionId(), AnswerEnum2.values()),
        new SimpleEntry<>(QuestionEnum3.getQuestionId(), AnswerEnum3.values()),
        new SimpleEntry<>(QuestionEnum4.getQuestionId(), AnswerEnum4.values()),
        new SimpleEntry<>(QuestionEnum5.getQuestionId(), AnswerEnum5.values()))
.collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())));

Tapi itu memberikan kesalahan "tidak dapat mengkonversi dari Map<Object,Object> ke Map<Long,Enum<? extends SomeEnum>[]>". Saya baru dalam hal ini. Tolong bantu!

Saya memerlukan peta Id pertanyaan yang tidak dapat dimodifikasi dengan kemungkinan nilai jawaban yang sesuai. Jawaban yang mungkin adalah Enum

Kemungkinan Jawaban dibungkus seperti ini:

public class RecognizedAnswers {
public enum AnswerEnum1 implements SomeInterface;
public enum Answer2 implements SomeInterface;
 }

person user3681970    schedule 09.04.2017    source sumber
comment
Jadi untuk setiap QuestionId ada kumpulan AnswerEnum yang sama, apakah berbeda?   -  person Beri    schedule 09.04.2017
comment
Mereka berbeda. Setiap AnswerEnum memperluas SomeEnum   -  person user3681970    schedule 09.04.2017
comment
Tapi itu tidak menyimpulkan. Dalam contoh Anda, Anda memiliki kumpulan jawaban, dan menurut deskripsi Anda perlu memetakan satu QuestioId ke satu Jawaban   -  person Beri    schedule 09.04.2017
comment
Saya memperbarui pertanyaannya. Karena saya mengubah nama variabel sebelum memposting pertanyaan, saya melewatkan poin itu. Setiap AnswerEnum memperluas SomeEnum   -  person user3681970    schedule 09.04.2017
comment
Di Jawa saya kira tidak mungkin untuk memperluas enum   -  person Alexander Kulyakhtin    schedule 09.04.2017
comment
itu benar, @AlexanderKulyakhtin   -  person Sharon Ben Asher    schedule 09.04.2017
comment
@AlexanderKulyakhtin ya.. itu adalah sebuah antarmuka. Saya telah memperbarui pertanyaannya. Jawaban di bawah ini masih memberikan kesalahan yang sama seperti yang disebutkan dalam pertanyaan. Tolong bantu!   -  person user3681970    schedule 09.04.2017
comment
Perhatikan bahwa sebenarnya adalah mungkin untuk memperluas enum (meskipun hanya di dalam definisi enum itu sendiri). implementasi metode khusus konstanta (dibahas dalam Java Efektif: Item 30) menyebabkan konstanta enum memperluas tipe enum, artinya MyEnum.getClass().equals(MyEnum.VALUE.getClass() terkadang dapat menghasilkan nilai salah. Berikut ini contoh dari pertanyaan SO.   -  person dimo414    schedule 11.04.2017


Jawaban (2)


Menurut saya, ada masalah kecil dalam penamaan:

Anda tidak dapat memperluas satu enum dengan enum lainnya di java, gunakan antarmuka dengan metode yang diinginkan, seperti di bawah ini

Dan kode di bawah ini berfungsi dengan baik:

   @Test
    public void test() {
        Map<Long, Enum<? extends SomeEnum>[]> questionIdToanswersMapping = Collections.unmodifiableMap(Stream.of(
                new AbstractMap.SimpleEntry<>(QuestionEnum1.A.getQuestionId(), AnswerEnum1.values()),
                new AbstractMap.SimpleEntry<>(QuestionEnum1.B.getQuestionId(), AnswerEnum1.values()),
                new AbstractMap.SimpleEntry<>(QuestionEnum1.C.getQuestionId(), AnswerEnum2.values()),
                new AbstractMap.SimpleEntry<>(QuestionEnum1.D.getQuestionId(), AnswerEnum2.values())
                )
                .collect(Collectors.toMap((e) -> e.getKey(), (e) -> e.getValue())));

        System.out.print(questionIdToanswersMapping.size());
    }

    enum QuestionEnum1 {
        A, B, C, D;

        Long getQuestionId() {
            return (long) name().hashCode(); // my mocked values
        }

    }

    interface SomeEnum {

    }

    enum AnswerEnum1 implements SomeEnum {

    }
    enum AnswerEnum2 implements SomeEnum {

    }
person Beri    schedule 09.04.2017
comment
Terima kasih! Intinya adalah Semua QuestionEnums dibungkus dalam satu kelas. Saya telah memperbarui pertanyaannya. Kode di atas memberikan kesalahan yang sama seperti yang disebutkan dalam pertanyaan - person user3681970; 09.04.2017

Saya mencoba mereplikasi contoh Anda (karena Anda mengaburkan tipe enum, saya membuatnya sendiri) dan tampaknya dapat dikompilasi dengan baik:

enum SomeEnum { FOO, BAR }

private Map<Long, Enum<? extends SomeEnum>[]> exampleMap =
    Collections.unmodifiableMap(Stream.of(
        new SimpleEntry<>(1L, SomeEnum.values()))
      .collect(Collectors.toMap(SimpleEntry::getKey, SimpleEntry::getValue)));

Dugaan saya adalah Anda memiliki tanda kurung yang hilang, atau QuestionEnum1.getQuestionId() Anda mengembalikan int daripada long, dan hal-hal tersebut cukup membingungkan kompiler sehingga tidak dapat memberikan pesan kesalahan yang jelas.

Saya perhatikan bahwa Stream API sebenarnya bukanlah cara yang bersih untuk membuat peta konstan. Membangun peta seperti itu "biasanya" dengan Map.put() kemungkinan akan lebih sederhana dan mudah dibaca, meskipun memerlukan blok static {} atau fungsi pembantu. Anda dapat melakukan lebih baik lagi dengan Guava koleksi yang tidak dapat diubah, yang dapat digunakan seperti ini:

private final ImmutableMap<Long, Enum<? extends SomeEnum>[]> questionIdToanswersMapping =
    ImmutableMap.builder()
        .put(QuestionEnum1.getQuestionId(), AnswerEnum1.values())
        .put(QuestionEnum2.getQuestionId(), AnswerEnum2.values())
        .put(QuestionEnum3.getQuestionId(), AnswerEnum3.values())
        .put(QuestionEnum4.getQuestionId(), AnswerEnum4.values())
        .put(QuestionEnum5.getQuestionId(), AnswerEnum5.values())
        .build();

Jauh lebih jelas dan lebih mudah untuk dibaca (dan ditulis).

person dimo414    schedule 09.04.2017