Java.util.Properties হ্যাশম্যাপ <স্ট্রিং, স্ট্রিং> এ রূপান্তর করা


92
Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>(properties);// why wrong?

java.util.Propertiesএটি একটি বাস্তবায়ন java.util.Map, এবং java.util.HashMapএর নির্মাণকারী একটি Mapপ্রকারের পরম প্রাপ্ত করে । সুতরাং, কেন এটি স্পষ্টভাবে রূপান্তর করা উচিত?

উত্তর:


88

এটি কারণ Propertiesপ্রসারিতHashtable<Object, Object> (যা ঘুরে, বাস্তবায়নগুলি Map<Object, Object>)। আপনি একটি এ খাওয়ানোর চেষ্টা Map<String, String>। সুতরাং এটি বেমানান।

আপনার মানচিত্রে একে একে স্ট্রিং বৈশিষ্ট্য খাওয়াতে হবে ...

এই ক্ষেত্রে:

for (final String name: properties.stringPropertyNames())
    map.put(name, properties.getProperty(name));

4
হ্যাঁ, তবে এখানে সমস্যাটি নেই: জেনেরিক যুক্তি মিলছে না। আপনি যা চান তা খাওয়াতে পারেন Hashtable<Object, Object>, এমনকী জিনিস যা স্ট্রিং নয় - এমন কীগুলিও যা স্ট্রিং নয়।
fge

@ এ্যাসেলিয়াস: না, এটিও সংকলন করবে না।
জন স্কিটি

13
1,8 এ আপনি বৈশিষ্ট্যগুলি করতে পারেন forএফ (প্রতিটি ((কে, ভি)) -> ম্যাপ.পুট ((স্ট্রিং) কে, (স্ট্রিং) ভি)));
ModdyFire

4
অথবা যদি ইতিমধ্যে হাতে থাকা বৈশিষ্ট্যগুলিতে মানচিত্র না থাকে ent )))
টনসিক

47

এটি করার দক্ষ উপায় হ'ল জেনেরিক মানচিত্রে নিচে দেওয়া:

Properties props = new Properties();

Map<String, String> map = (Map)props;

এটি Map<Object, Object>কোনও কাঁচা মানচিত্রে রূপান্তরিত করবে যা সংকলকটির জন্য "ঠিক আছে" (কেবলমাত্র সতর্কতা)। একবার আমাদের কাঁচা Mapহয়ে গেলে এটি নিক্ষেপ হবে Map<String, String>যা এটি "ওকে" (অন্য একটি সতর্কতা) হবে। আপনি এটিকে টীকা দিয়ে উপেক্ষা করতে পারেন@SuppressWarnings({ "unchecked", "rawtypes" })

এটি কাজ করবে কারণ JVM- তে বস্তুর আসলে জেনেরিক টাইপ নেই। জেনেরিক প্রকারগুলি হ'ল একটি কৌশল যা সংকলনের সময় জিনিসগুলি যাচাই করে।

যদি কিছু কী বা মান স্ট্রিং না হয় তবে এটি ClassCastExceptionত্রুটি তৈরি করবে । বর্তমান সঙ্গে Propertiesবাস্তবায়ন এই যতদিন না পর্যন্ত আপনি সুপার থেকে চপল কল পদ্ধতি ব্যবহার করবেন না খুবই ঘটতে সম্ভাবনা কম, Hashtable<Object,Object>এর Properties

সুতরাং, যদি আপনার সম্পত্তিগুলির উদাহরণের সাথে খারাপ কিছু না করে তবে এই উপায়।


প্রশ্নটি হ্যাশম্যাপে রূপান্তরিত। কোনও মানচিত্র নয়।
অ্যালিকেলজিন-কিলাকা

4
হ্যাঁ, প্রশ্নের শিরোনামে এটি বলা হয়েছে, তবে লক্ষ্যটি Mapঅন্তত প্রদত্ত কোডে একটি উদাহরণ থাকা উচিত, তাই আমি ভেবেছিলাম যে এটিই তার প্রয়োজন
প্যাডিলো

যদিও আমি অন্যান্য পিউরিস্ট সমাধানগুলি পছন্দ করি তবে এই সমাধানটি আমার কাছে কার্যকর কারণ এটি কেবল একটি সহজ লাইন।
আলফোনসো নিশিকাওয়া


28

এ কেমন?

   Map properties = new Properties();
   Map<String, String> map = new HashMap<String, String>(properties);

একটি সতর্কতা সৃষ্টি করবে, তবে পুনরাবৃত্তি ছাড়াই কাজ করবে।


4
@fge: এটি একটি নয় Map<Object, Object>, এটি একটি Mapযুক্তি (কাঁচা টাইপ)। এই উত্তরটি সঠিক
লুকাশ এডার

4
হু, হ্যাঁ আমি Eclipse দিয়ে চেষ্টা করেছি। আবার একটি গ্রহ এবং জাভাকের মধ্যে যে জেনেরিক পার্থক্য রয়েছে? .... না, জাভাকের সাথেও কাজ করে
লুকাশ এডার

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

পূর্ববর্তী উত্তরটি যেমন বলেছে, কোনও নতুন উদাহরণ তৈরি করার এবং বৈশিষ্ট্যগুলির বস্তুর উপরে পুনরাবৃত্তি করার দরকার নেই। কেবল কাস্টের ক্রম ব্যবহার করুন: (Map<String, String>) ((Map) properties)
রিকার্ডো ভেলোসো

23

জাভা 8 উপায়:

properties.entrySet().stream().collect(
    Collectors.toMap(
         e -> e.getKey().toString(),
         e -> e.getValue().toString()
    )
);

লাম্বদার পরিবর্তে পদ্ধতি রেফারেন্স ব্যবহার করার কোনও উপায় আছে কি? সোনার কোয়েব ইস্যুগুলি অনেক বেশি।
ভায়ান ঝিঙ্গাদে

17

Properties প্রয়োগ Map<Object, Object> - না Map<String, String>

আপনি এই নির্মাণকারীকে কল করার চেষ্টা করছেন:

public HashMap(Map<? extends K,? extends V> m)

... সঙ্গে K এবং Vউভয় হিসাবে String

কিন্তু Map<Object, Object> এটি একটি নয় Map<? extends String, ? extends String>... এতে নন-স্ট্রিং কী এবং মান থাকতে পারে।

এটি কাজ করবে:

Map<Object, Object> map = new HashMap<Object, Object>();

... তবে এটি আপনার পক্ষে তেমন কার্যকর হবে না।

মৌলিকভাবে, Propertiesকখনও কখনও এর সাবক্লাস করা উচিত ছিল না HashTable... এটাই সমস্যা। ভি 1 এর পরে, উদ্দেশ্যটির বিরুদ্ধে থাকা সত্ত্বেও, এটি সর্বদা নন-স্ট্রিং কী এবং মানগুলি সঞ্চয় করতে সক্ষম হয়। পরিবর্তে যদি রচনাটি ব্যবহার করা হত, তবে API এ থাকতে পারে কেবল স্ট্রিং কী / মান দিয়ে কাজ এবং সমস্ত কিছু ঠিকঠাক হত।

আপনি এই জাতীয় কিছু পেতে পারেন:

Map<String, String> map = new HashMap<String, String>();
for (String key : properties.stringPropertyNames()) {
    map.put(key, properties.getProperty(key));
}

স্পষ্টতই এটি পরিষ্কারভাবে করা সম্ভবও নয় Properties<String,String> properties = new Properties<String,String>();। অদ্ভুত
eis

4
@ এটি ডিজাইন অনুসারে, Propertiesনিজে জেনেরিক নয়।
ম্যাটিয়াস বুয়েলেস

আমি বরং এটি ডিজাইনের পরিবর্তে দুর্ভাগ্যজনক সিরিজের পছন্দ অনুসারে বলতে চাই, তবে হ্যাঁ।
eis

4
@ আইস: না, এটি ডিজাইনের মাধ্যমে যে সম্পত্তিগুলি বোঝানো হয় স্ট্রিং-টু-স্ট্রিং মানচিত্র। এটি জেনারিক নয় তা বোঝায়। এটা তোলে নেই এই অর্থে যে আপনি অ স্ট্রিং কী / মান যোগ করতে পারেন ভুলবেন না।
জন স্কিটে


8

যদি আপনি জানেন যে আপনার Propertiesঅবজেক্টটিতে কেবল প্রবেশ রয়েছে <String, String>, তবে আপনি কোনও কাঁচা ধরণের অবলম্বন করতে পারেন:

Properties properties = new Properties();
Map<String, String> map = new HashMap<String, String>((Map) properties);

4

সমস্যাটি হ'ল Propertiesপ্রয়োগকারীরা Map<Object, Object>, যেখানে HashMapকনস্ট্রাক্টর একটির প্রত্যাশা করে Map<? extends String, ? extends String>

এই উত্তরটি এই (যথেষ্ট পাল্টা স্বজ্ঞাত) সিদ্ধান্তটি ব্যাখ্যা করে। সংক্ষেপে: জাভা 5 এর আগে Propertiesকার্যকর করা Map( আগে কোনও জেনেরিক ছিল না)। এর অর্থ আপনি করা হতে পারে কোন Object একটি Propertiesঅবজেক্ট। এটি এখনও নথিপত্রের মধ্যে রয়েছে:

কারণ Properties উত্তরাধিকার সূত্রে প্রাপ্ত Hashtable, তাই কোনও পদ্ধতিতে putএবং putAllপদ্ধতিগুলি প্রয়োগ করা যেতে পারে Properties। যার ব্যবহারকারীর চাবি বা মানগুলি নয় সেগুলি প্রবেশকারী প্রবেশ করানোর জন্য কলারের অনুমতি দেওয়ার কারণে তাদের ব্যবহার দৃ strongly়ভাবে নিরুৎসাহিত StringsetPropertyপদ্ধতি পরিবর্তে ব্যবহার করা উচিত।

এর সাথে সামঞ্জস্যতা বজায় রাখার জন্য, ডিজাইনারদের এটি Map<Object, Object>জাভা ৫-এ উত্তরাধিকারী করা ছাড়া অন্য কোনও উপায় ছিল না, এটি পুরো পিছনের সামঞ্জস্যের জন্য প্রচেষ্টা করার দুর্ভাগ্যজনক ফলাফল যা নতুন কোডকে অহেতুকভাবে সংশ্লেষিত করে তোলে।

আপনি শুধুমাত্র কখনও আপনার স্ট্রিং বৈশিষ্ট্য ব্যবহার করলে Propertiesবস্তু, আপনি উচিত আপনার কন্সট্রাকটর একটি অবারিত ঢালাই দিয়ে পার পেতে পাবে:

Map<String, String> map = new HashMap<String, String>( (Map<String, String>) properties);

বা কোনও অনুলিপি ছাড়াই:

Map<String, String> map = (Map<String, String>) properties;

এটি হ্যাশম্যাপ কনস্ট্রাক্টরের স্বাক্ষর public HashMap(Map<? extends K, ? extends V> m)। এটি প্রত্যাশা করে নাMap<String, String>
মুবিন

@ মুবিন ঠিক আছে, আমি বিষয়টি কিছুটা বড় করে দিয়েছি। তবুও, যুক্তিটি ধরে রেখেছে: একটি Map<Object, Object>টাইপ করা হচ্ছে <মানচিত্র <? স্ট্রিং প্রসারিত,? স্ট্রিং> extend প্রসারিত `
ম্যাটিয়াস বুয়েলেস

2

এটি কেবলমাত্র হ্যাশম্যাপের নির্মাতার জন্য মানচিত্রের জেনেরিক প্রকারের একটি আরগের প্রয়োজন হয় এবং সম্পত্তিগুলি মানচিত্র প্রয়োগ করে।

এটি কাজ করবে, যদিও একটি সতর্কতা সহ

    Properties properties = new Properties();
    Map<String, String> map = new HashMap(properties);

1

আপনি এটি ব্যবহার করতে পারেন:

Map<String, String> map = new HashMap<>();

props.forEach((key, value) -> map.put(key.toString(), value.toString()));

0

প্রথম জিনিস,

প্রোপার্টি ক্লাস হ্যাশটেবলের উপর ভিত্তি করে না হ্যাশম্যাপের উপর ভিত্তি করে। প্রোপার্টি ক্লাস মূলত হ্যাশটেবল প্রসারিত করে

হ্যাশম্যাপ ক্লাসে এমন কোনও কনস্ট্রাক্টর নেই যা কোনও বৈশিষ্ট্য অবজেক্ট নেয় এবং আপনাকে একটি হ্যাশম্যাপ অবজেক্ট দেয়। সুতরাং আপনি যা করছেন তা সঠিক নয়। আপনার বৈশিষ্ট্যগুলির বস্তুটি হ্যাশটেবল রেফারেন্সে কাস্ট করতে সক্ষম হওয়া উচিত।


0

আমি এটি ব্যবহার:

for (Map.Entry<Object, Object> entry:properties.entrySet()) {
    map.put((String) entry.getKey(), (String) entry.getValue());
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.