ইন ভ্যালুতে এনাম যুক্ত হচ্ছে associated


89

পূর্বে, আমি আমার লেগনো এনামগুলিকে সহজভাবে সংজ্ঞায়িত করেছি:

NO_LEG, LEG_ONE, LEG_TWO

এবং কল করে return LegNo.values()[i];আমি প্রতিটি এনামের সাথে সম্পর্কিত মান পেতে সক্ষম হয়েছি।

তবে আমি এখন সিদ্ধান্ত নিয়েছি যে LegNoএনামটি NO_LEG0 এর পরিবর্তে এন -1 হতে চাই তাই আমি প্রাইভেট কনস্ট্রাক্টরটি আরম্ভ করার জন্য ব্যবহার করব এবং এর মান নির্ধারণ করব

NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

private LegNo(final int leg) { legNo = leg; }

এখন কেবল একটাই কারণ আমি এটি এইভাবে করছি কারণ values()পদ্ধতিটি NO_LEGএনামের পক্ষে কাজ করবে না । আমি কীভাবে ইনমের সাথে যুক্ত হব? কেস স্যুইচ স্টেটমেন্ট বা যদি-ifif-elseif ব্যবহার না করে এটি করার অন্য কোনও কার্যকর উপায় আছে?

এনাম থেকে ইনট মান পাওয়ার ক্ষেত্রে আমি অনেকগুলি এসও প্রশ্ন দেখতে পাচ্ছি তবে আমি তার বিপরীতে আছি।

উত্তর:


149

EDIT আগস্ট 2018

আজ আমি নিম্নলিখিত হিসাবে এটি বাস্তবায়ন করা হবে

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private final int value;

    LegNo(int value) {
        this.value = value;
    }

    public static Optional<LegNo> valueOf(int value) {
        return Arrays.stream(values())
            .filter(legNo -> legNo.value == value)
            .findFirst();
    }
}

এনামের ভিতরে আপনাকে একটি ম্যাপিং বজায় রাখতে হবে।

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private int legNo;

    private static Map<Integer, LegNo> map = new HashMap<Integer, LegNo>();

    static {
        for (LegNo legEnum : LegNo.values()) {
            map.put(legEnum.legNo, legEnum);
        }
    }

    private LegNo(final int leg) { legNo = leg; }

    public static LegNo valueOf(int legNo) {
        return map.get(legNo);
    }
}

স্ট্যাটিক ব্লকটি কেবল একবারই ডাকা হবে, সুতরাং এখানে কার্যত কোনও কার্য সম্পাদনের সমস্যা নেই।

সম্পাদনা: valueOfঅন্যান্য জাভা ক্লাসগুলির সাথে এটি আরও ইনলাইন হওয়ায় পদ্ধতিটির নামকরণ হয়েছে ।


দুঃখিত আমি নিশ্চিত না আমি যথেষ্ট পরিষ্কার ছিল কিনা। আমি ইনটি পাস করতে এবং এটির সাথে এনাম যুক্ত করতে চাই।
এল-সামুয়েলস

@ এল-স্যামুয়েলস অনুমান আমি আপনার প্রশ্নটি সঠিকভাবে পড়িনি। আমার আপডেট দেখুন।
আদর্শ

4
আমি জানি এই সুস্পষ্ট বলে মনে হয়, কিন্তু এটা তাই মত ব্যবহার করুন: LegNo foo = LegNo.valueOf(2);। পূর্ববর্তী কোডটি ফিরে আসবে a LegNo.LEG_TWO
ফার্স্টনে

4
লক্ষণীয় যে, একটি অবৈধ পূর্ণসংখ্যার মান (ম্যাপ করা হয়নি) পাস nullকরা প্রত্যাশার সাথে প্রত্যাশার সাথে প্রত্যাবর্তন করবে হ্যাশম্যাপ.জেট : নির্দিষ্ট কীটি ম্যাপ করা হয়েছে এমন মানটি ফেরত দেয় বা যদি এই মানচিত্রে কীটির জন্য কোনও ম্যাপিং না থাকে তবে শূন্য হয়।
ফার্স্টনে

স্ট্রিম সিনট্যাক্সটি ঝরঝরে হলেও এটি উল্লেখ করার মতো যে এটি স্থির মানচিত্রের চেয়ে বেশি সময় জটিলতা রয়েছে (যা স্বীকার করে যে এর চেয়ে বেশি স্মৃতি খরচ হয়)। 3 টি মানের জন্য কোনও সমস্যা নয়, তবে আপনি যদি valueOf()অন্য লুপের মধ্যে 1000 সদস্যের এনামকে প্রবেশ করিয়ে থাকেন তবে অবশ্যই একটি উদ্বেগ ।
প্যাট্রিক এম

24

আপনি এনামে এমন একটি স্ট্যাটিক পদ্ধতিও অন্তর্ভুক্ত করতে পারেন যা সমস্ত সদস্যের মাধ্যমে পুনরাবৃত্তি করে এবং সঠিকটি প্রদান করে।

public enum LegNo {
   NO_LEG(-1),
   LEG_ONE(1),
   LEG_TWO(2);

   private int legIndex;

   private LegNo(int legIndex) { this.legIndex = legIndex; }

   public static LegNo getLeg(int legIndex) {
      for (LegNo l : LegNo.values()) {
          if (l.legIndex == legIndex) return l;
      }
      throw new IllegalArgumentException("Leg not found. Amputated?");
   }
}

এখন, আপনি যদি পূর্ণসংখ্যার দ্বারা এনুম মান পেতে চান তবে আপনি কেবল ব্যবহার করুন:

int myLegIndex = 1; //expected : LEG_ONE
LegNo myLeg = LegNo.getLeg(myLegIndex);

আমি মনে করি এটি যদি অন্য বিবরণী বিবৃতি ব্যবহারের চেয়ে আরও মার্জিত হয়। তবে প্রদত্ত আরও কিছু নিখরচায় অনুসন্ধানের পরে @arshr এর প্রস্তাবিত মানচিত্র কৌশলটি আরও ভাল হবে। যদিও হাস্যরসটির পক্ষে ভোট দিন।
এল-সামুয়েলস

4
আমি মানচিত্র কৌশলটিও অনেক পছন্দ করি। বিশেষত যখন এনামের হয় প্রচুর মান থাকে বা খুব প্রায়ই এই প্রক্রিয়াটির মাধ্যমে সন্ধান করতে হয়। যাইহোক, যদি সম্পর্কিত ইন্টের দ্বারা মানগুলি অপেক্ষাকৃত বিরল ঘটনা বা আপনার একই রকমের প্রয়োজনীয়তার সাথে অনেকগুলি আলাদা এনাম থাকে তবে আমি বিশ্বাস করি যে মানচিত্রের ওভারহেড সংরক্ষণ করা হওয়ায় আমার উপায়টি আরও সংস্থানবান্ধব হবে। এছাড়াও, আমি এটি কম বিশৃঙ্খলাযুক্ত কোডের জন্য খুঁজে পেয়েছি। আমার কয়েকটি ব্যবহারের কেস রয়েছে যেখানে আমি অবশ্যই ম্যাপ-টাইপটিতে নিজেই স্যুইচ করব।
মাইক অ্যাডলার

আপনার কখনই কোনও সম্পর্কিত এনাম মান এর অর্ডিনাল দ্বারা নেওয়া উচিত নয়। একটি স্থিতিশীল মানচিত্র ব্যবহার করা জাভা স্থপতিদের প্রস্তাবিত পদ্ধতি ology
hfontanez

এই উদাহরণস্বরূপ লেজআইন্ডেক্স ক্ষেত্রটি অর্ডিনালের সাথে মিলে যায় তবে কোনও মান মান হতে পারে। কোনও অর্ডিনাল লুকআপ করা হয় না। এছাড়াও, দয়া করে আপনার কেন অর্ডিনাল চেহারা খারাপ বলে মনে করেন তার একটি কারণ দিন বা লিঙ্ক করুন।
মাইক অ্যাডলার 18

4
"লেগ পাওয়া যায় নি। চলা?"
গাগনি

17

আদর্শের উত্তর জাভা 8 তে অভিযোজিত:

import static java.util.Arrays.stream;
import static java.util.stream.Collectors.toMap;

import java.util.Map;

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private final int legNo;

    private final static Map<Integer, LegNo> map =
            stream(LegNo.values()).collect(toMap(leg -> leg.legNo, leg -> leg));

    private LegNo(final int leg) {
        legNo = leg;
    }

    public static LegNo valueOf(int legNo) {
        return map.get(legNo);
    }
}

11

আপনি শুধুমাত্র এনাম লেগনোতে মানগুলি () পদ্ধতিতে কল করে প্রদত্ত পূর্ণসংখ্যার মানের সাথে এনাম মানটি অ্যাক্সেস করতে পারেন। এটি লেগনো এনামদের ক্ষেত্রটি প্রত্যাবর্তন করবে: LegNo.values()[0]; //returns LEG_NO LegNo.values()[1]; //returns LEG_ONE LegNo.values()[2]; //returns LEG_TWO

তিনি যে জিনিসটি সন্ধান করেছিলেন ঠিক তা নয়, তবে খুব কাছাকাছি এবং খুব সহজ simple (যদিও বিষয়টি মারা গেছে এটি অন্য কারও জন্য কার্যকর হতে পারে))


6

ডিফল্ট মান সহ জাভা 8 উপায়:

public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private final int legNo;

    LegNo(int legNo) {
        this.legNo = legNo;
    }

    public static LegNo find(int legNo, Supplier<? extends LegNo> byDef) {
        return Arrays.asList(LegNo.values()).stream()
                .filter(e -> e.legNo == legNo).findFirst().orElseGet(byDef);
    }
}

কল করতে:

LegNo res = LegNo.find(0, () -> LegNo.NO_LEG);

বা ব্যতিক্রম সহ:

LegNo res = LegNo.find(0, () -> {
    throw new RuntimeException("No found");
});

2
public enum LegNo {

  NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

  private final int code;

  LegNo(int code) {
    this.code = code;
    ReverseStorage.reverseMap.put(code, this);
  }

  public static Optional<LegNo> getByCode(int code) {
    return Optional.ofNullable(ReverseStorage.reverseMap.get(code));
  }

  private static final class ReverseStorage {
    private static final Map<Integer, LegNo> reverseMap = new LinkedHashMap<>();
  }
}

1

যেহেতু আপনার এনামটিতে কেবলমাত্র 3 টি উপাদান রয়েছে, আপনার দ্রুত if elseপ্রস্তাব দেওয়ার মতো দ্রুততম উপায়টি কেবল একটি সিরিজ ব্যবহার করা হবে ।

সম্পাদনা করুন: আদর্শ প্রদত্ত উত্তরটি সাধারণ ক্ষেত্রে উপযুক্ত, যেখানে অনেকগুলি এনাম মান রয়েছে তবে আমি মনে করি এটি আপনার সমস্যার জন্য একটি ওভারকিল।


একটি হচ্ছে Mapআপনার কোডে অবশ্যই একটি Overkill নয়। এছাড়াও এটি যদি অন্য কোনও শর্তের স্প্যাগেটির চেয়ে পদ্ধতিটিকে অনেক পরিষ্কার করে তোলে।
আদর্শ

আমি সম্মত হই যে একবার আপনার প্রচুর এনাম মান থাকলে মানচিত্রটি আরও ভাল হয় তবে 3 টি মানের জন্য আমি যদি / অন্যটি নির্মাণ করে থাকি। আমার ধারণা এটি স্বাদের বিষয়।
ডিয়েটারডিপি

আমরা যাই হোক না কেন পদ্ধতির নির্বাচন পদ্ধতির স্বাক্ষর public LegNo valueOf(int value)পরিবর্তন করা উচিত নয়। যদি-অন্যটি তখন এনামের মধ্যেই লেখা যায়। যদি-অন্যটি এনামের বাইরে চলে যায় তবে তা অবশ্যই একটি পরিষ্কার-পরিচ্ছন্ন কোডে পরিণত হয়।
আদর্শ

4
আমি আপনার সাথে পুরোপুরি একমত আছি :)
ডিটারডিডি

1
public enum LegNo {
    NO_LEG(-1), LEG_ONE(1), LEG_TWO(2);

    private int legNo;

    private LegNo(int leg) { legNo = leg; }

    public static LegNo valueOf(int legNo) {
        for (LegNo leg : LegNo.values()) {
            if (leg.legNo == legNo) return leg;
        }   
    }
}

assert LegNo.valueOf(2) == LegNo.LEG_TWO
assert LegNo.valueOf(3) == null

4
<10 টি মান সহ এনামগুলির জন্য গ্রহণযোগ্য তবে অনুসন্ধানের জটিলতার কারণে এন (এন) এর বিশাল সংখ্যক এনম মানগুলির জন্য সম্পূর্ণ অকার্যকর
আলফিশ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.