আমি এই ধরণের জিনিসটিকে কীভাবে কাজ করতে পারি? আমি যদি না পরীক্ষা (obj instanceof List<?>)
করতে পারেন (obj instanceof List<MyType>)
। এটি করার কোনও উপায় আছে কি?
আমি এই ধরণের জিনিসটিকে কীভাবে কাজ করতে পারি? আমি যদি না পরীক্ষা (obj instanceof List<?>)
করতে পারেন (obj instanceof List<MyType>)
। এটি করার কোনও উপায় আছে কি?
উত্তর:
এটি সম্ভব নয় কারণ জেনেরিকগুলির সংকলনের সময় ডেটাটাইপ মোছা। এটি করার একমাত্র সম্ভাব্য উপায় হ'ল কিছু ধরণের র্যাপার লিখুন যা তালিকায় কোন ধরণের ধারণ করে:
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;
}
}
if(!myList.isEmpty() && myList.get(0) instanceof MyType){
// MyType object
}
value
যা প্রত্যাবর্তন করবে Object
এবং আমার চেক করা দরকার - এটি যদি একটি তালিকা থাকে তবে তা যদি হয় তবে আমার ইন্টারফেসের তালিকার তালিকাটি পরীক্ষা করে দেখুন কিনা check কোনও মোড়ক বা প্যারামেট্রাইজড টাইপ এখানে দরকারী।
এগুলির ধরণগুলি পরীক্ষা করার জন্য আপনার সম্ভবত প্রতিবিম্ব ব্যবহার করা দরকার। তালিকার ধরণটি পেতে : জেনারিক প্রকারের java.util.List পান
এটি 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.
}
}
if (list instanceof List && ((List) list).stream()
.noneMatch((o -> !(o instanceof MyType)))) {}
যদি আপনি যাচাই করেন যদি কোনও তালিকার কোনও তালিকা বা মানচিত্রের মানটির কোনও সংগ্রহের উদাহরণ, কেবল প্রয়োজনীয় তালিকার একটি উদাহরণ তৈরি করুন এবং এর শ্রেণিটি পাবেন ...
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
?
যদি এটি জেনেরিকের সাথে জড়িত না করা যায় (@ মার্তিজানের উত্তর) অপ্রয়োজনীয় তালিকার পুনরাবৃত্তি এড়ানোর জন্য 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 );
}
}
উদাহরণস্বরূপ ব্যবহারের পরিবর্তে আপনি অনেকগুলি পদ্ধতিতে জাল কারখানাটি ব্যবহার করতে পারেন:
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);
}
}
এখানে প্রধান উদ্বেগটি হ'ল সংগ্রহগুলি সংজ্ঞাটির ধরণটি রাখে না। প্রকারগুলি কেবল রানটাইমে পাওয়া যায়। জটিল সংগ্রহগুলি পরীক্ষা করার জন্য আমি একটি ফাংশন নিয়ে এসেছি (এটির একটি সীমাবদ্ধতা রয়েছে)।
বস্তুটি জেনেরিক সংগ্রহের উদাহরণ কিনা তা পরীক্ষা করুন। কোনও সংগ্রহ উপস্থাপন করার জন্য,
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;
}