<মাই টাইপ> তালিকা কীভাবে উপস্থাপন করবেন?


88

আমি এই ধরণের জিনিসটিকে কীভাবে কাজ করতে পারি? আমি যদি না পরীক্ষা (obj instanceof List<?>)করতে পারেন (obj instanceof List<MyType>)। এটি করার কোনও উপায় আছে কি?



উত্তর:


49

এটি সম্ভব নয় কারণ জেনেরিকগুলির সংকলনের সময় ডেটাটাইপ মোছা। এটি করার একমাত্র সম্ভাব্য উপায় হ'ল কিছু ধরণের র‌্যাপার লিখুন যা তালিকায় কোন ধরণের ধারণ করে:

public class GenericList <T> extends ArrayList<T>
{
     private Class<T> genericType;

     public GenericList(Class<T> c)
     {
          this.genericType = c;
     }

     public Class<T> getGenericType()
     {
          return genericType;
     }
}

ধন্যবাদ, আমি মনে করি যে আমি দুটি ফাংশন যাচাই বাছাই করার জন্য ফোন করছি সেই ফাংশনটিতে আমি জেনেরিক টাইপটি পাস করব।
রকি পুলি

আপনি উদাহরণ দিয়ে বিস্তারিত বর্ণনা করতে পারেন
তিরুমাল

31
if(!myList.isEmpty() && myList.get(0) instanceof MyType){
    // MyType object
}

7
... এবং খালি তালিকার জন্য? প্রতিচ্ছবি?
Gewure

ইয়াপ খালি তালিকার জন্য এটিই একমাত্র বিকল্প। stackoverflow.com/questions/1942644/…
সতীশ

12
এই উত্তরটি নিরাপদ নয়, কারণ 0 উপাদানটি মাইটাইপ হলেও, অন্যান্য উপাদানগুলি অন্য ধরণের হতে পারে। উদাহরণস্বরূপ, সম্ভবত তালিকাটি অ্যারেলিস্ট <ওজেক্ট> হিসাবে ঘোষিত হয়েছিল, তারপরে একটি মাইটাইপ যুক্ত হয়েছিল এবং তারপরে একটি স্ট্রিং যুক্ত হয়েছিল।
অ্যাডাম গাওনে-কেইন

@ অ্যাডামগাউন-কেইন এটি নিরাপদ নয়, তবে দুর্ভাগ্যজনকভাবে এই তালিকা সম্পর্কে খুব বেশি কিছু না জেনে একমাত্র সমাধান। উদাহরণস্বরূপ - আমার কাছে স্থানীয় ভেরিয়েবল রয়েছে valueযা প্রত্যাবর্তন করবে Objectএবং আমার চেক করা দরকার - এটি যদি একটি তালিকা থাকে তবে তা যদি হয় তবে আমার ইন্টারফেসের তালিকার তালিকাটি পরীক্ষা করে দেখুন কিনা check কোনও মোড়ক বা প্যারামেট্রাইজড টাইপ এখানে দরকারী।
সকেটবাইট

মাইলিস্ট কোথায় ঘোষিত হয়?
ইগোরগানাপলস্কি

9

এগুলির ধরণগুলি পরীক্ষা করার জন্য আপনার সম্ভবত প্রতিবিম্ব ব্যবহার করা দরকার। তালিকার ধরণটি পেতে : জেনারিক প্রকারের java.util.List পান


4
আমি যতদূর জানি, এটি কেবল ক্ষেত্রের জন্য কাজ করে তবে এটি উল্লেখ করার জন্য +1।
টিম পোট

6

এটি objectউদাহরণস্বরূপ List<T>যা খালি নয় তা পরীক্ষা করতে চাইলে এটি ব্যবহার করা যেতে পারে :

if(object instanceof List){
    if(((List)object).size()>0 && (((List)object).get(0) instanceof MyObject)){
        // The object is of List<MyObject> and is not empty. Do something with it.
    }
}


1

যদি আপনি যাচাই করেন যদি কোনও তালিকার কোনও তালিকা বা মানচিত্রের মানটির কোনও সংগ্রহের উদাহরণ, কেবল প্রয়োজনীয় তালিকার একটি উদাহরণ তৈরি করুন এবং এর শ্রেণিটি পাবেন ...

Set<Object> setOfIntegers = new HashSet(Arrays.asList(2, 4, 5));
assetThat(setOfIntegers).instanceOf(new ArrayList<Integer>().getClass());

Set<Object> setOfStrings = new HashSet(Arrays.asList("my", "name", "is"));
assetThat(setOfStrings).instanceOf(new ArrayList<String>().getClass());

আপনার setOfIntegersএবং এর বিন্দুটি কী setOfStrings?
ড্যানিয়েল

@ ড্যানিয়েল স্যাম্পলটি সবেমাত্র আপডেট করেছেন। এটি অবশ্যই এই রেফারেন্স ব্যবহার করা হবে! ধন্যবাদ!
মার্সেলো দে বিক্রয়

1

যদি এটি জেনেরিকের সাথে জড়িত না করা যায় (@ মার্তিজানের উত্তর) অপ্রয়োজনীয় তালিকার পুনরাবৃত্তি এড়ানোর জন্য ingালাই ছাড়াই উত্তরণ করা ভাল (প্রথম উপাদানটির ধরণটি কোনও কিছুর নিশ্চয়তা দেয় না)। আমরা কোডটির টুকরোটিতে প্রতিটি উপাদান নিক্ষেপ করতে পারি যেখানে আমরা তালিকাটি পুনরাবৃত্তি করি।

Object attVal = jsonMap.get("attName");
List<Object> ls = new ArrayList<>();
if (attVal instanceof List) {
    ls.addAll((List) attVal);
} else {
    ls.add(attVal);
}

// far, far away ;)
for (Object item : ls) {
    if (item instanceof String) {
        System.out.println(item);
    } else {
        throw new RuntimeException("Wrong class ("+item .getClass()+") of "+item );
    }
}

0

উদাহরণস্বরূপ ব্যবহারের পরিবর্তে আপনি অনেকগুলি পদ্ধতিতে জাল কারখানাটি ব্যবহার করতে পারেন:

public class Message1 implements YourInterface {
   List<YourObject1> list;
   Message1(List<YourObject1> l) {
       list = l;
   }
}

public class Message2 implements YourInterface {
   List<YourObject2> list;
   Message2(List<YourObject2> l) {
       list = l;
   }
}

public class FactoryMessage {
    public static List<YourInterface> getMessage(List<YourObject1> list) {
        return (List<YourInterface>) new Message1(list);
    }
    public static List<YourInterface> getMessage(List<YourObject2> list) {
        return (List<YourInterface>) new Message2(list);
    }
}

0

এখানে প্রধান উদ্বেগটি হ'ল সংগ্রহগুলি সংজ্ঞাটির ধরণটি রাখে না। প্রকারগুলি কেবল রানটাইমে পাওয়া যায়। জটিল সংগ্রহগুলি পরীক্ষা করার জন্য আমি একটি ফাংশন নিয়ে এসেছি (এটির একটি সীমাবদ্ধতা রয়েছে)।

বস্তুটি জেনেরিক সংগ্রহের উদাহরণ কিনা তা পরীক্ষা করুন। কোনও সংগ্রহ উপস্থাপন করার জন্য,

  • সর্বদা কোন ক্লাস নেই false
  • এক শ্রেণি, এটি সংগ্রহ নয় এবং instanceofমূল্যায়নের ফলাফল প্রদান করে
  • একটি Listবা প্রতিনিধিত্ব Setকরতে তালিকার ধরণটি পরবর্তী যেমন {তালিকা, পূর্ণসংখ্যা} এর জন্য আসেList<Integer>
  • একটি উপস্থাপন করতে Map, কী এবং মানের ধরণগুলি পরবর্তী যেমন eg মানচিত্র, স্ট্রিং, পূর্ণসংখ্যা come এর জন্য আসেMap<String, Integer>

একই নিয়ম ব্যবহার করে আরও জটিল ব্যবহারের ক্ষেত্রে উত্পন্ন করা যেতে পারে। উদাহরণস্বরূপ উদাহরণস্বরূপ List<Map<String, GenericRecord>>, এটি হিসাবে বলা যেতে পারে

    Map<String, Integer> map = new HashMap<>();
    map.put("S1", 1);
    map.put("S2", 2);
    List<Map<String, Integer> obj = new ArrayList<>();
    obj.add(map);
    isInstanceOfGenericCollection(obj, List.class, List.class, Map.class, String.class, GenericRecord.class);

নোট করুন যে এই বাস্তবায়ন মানচিত্রে নেস্টেড প্রকারকে সমর্থন করে না। অতএব, কী এবং মানের ধরণটি একটি ক্লাস হতে হবে এবং সংগ্রহ নয়। তবে এটি যুক্ত করা শক্ত হওয়া উচিত নয়।

    public static boolean isInstanceOfGenericCollection(Object object, Class<?>... classes) {
        if (classes.length == 0) return false;
        if (classes.length == 1) return classes[0].isInstance(object);
        if (classes[0].equals(List.class))
            return object instanceof List && ((List<?>) object).stream().allMatch(item -> isInstanceOfGenericCollection(item, Arrays.copyOfRange(classes, 1, classes.length)));
        if (classes[0].equals(Set.class))
            return object instanceof Set && ((Set<?>) object).stream().allMatch(item -> isInstanceOfGenericCollection(item, Arrays.copyOfRange(classes, 1, classes.length)));
        if (classes[0].equals(Map.class))
            return object instanceof Map &&
                    ((Map<?, ?>) object).keySet().stream().allMatch(classes[classes.length - 2]::isInstance) &&
                    ((Map<?, ?>) object).values().stream().allMatch(classes[classes.length - 1]::isInstance);
        return false;
    }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.