আমি কীভাবে জাভা স্ট্রিংয়ের ইউনিকোড কোডপয়েন্টগুলিতে পুনরাবৃত্তি করতে পারি?


105

সুতরাং আমি জানি String#codePointAt(int), তবে এটি charঅফসেট দ্বারা সূচিযুক্ত, কোডপয়েন্ট অফসেট দ্বারা নয়।

আমি এরকম কিছু চেষ্টা করার বিষয়ে ভাবছি:

তবে আমার উদ্বেগগুলি

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

উত্তর:


143

হ্যাঁ, জাভা স্ট্রিংগুলির অভ্যন্তরীণ উপস্থাপনের জন্য একটি ইউটিএফ-16-এস্কো এনকোডিং ব্যবহার করে এবং হ্যাঁ, এটি বেসিক বহুভাষিক সমতল ( বিএমপি) এর বাইরে অক্ষরগুলি এনকোড করে স্কিমটি ব্যবহার করে ) করে।

আপনি যদি জানেন যে আপনি বিএমপির বাইরে অক্ষরগুলি নিয়ে কাজ করছেন, তবে জাভা স্ট্রিংয়ের অক্ষরগুলি পুনরুক্ত করার জন্য এখানে প্রচলিত উপায় রয়েছে:

final int length = s.length();
for (int offset = 0; offset < length; ) {
   final int codepoint = s.codePointAt(offset);

   // do something with the codepoint

   offset += Character.charCount(codepoint);
}

2
এটি "ব্যয়বহুল" কিনা, ঠিক আছে ... জাভাতে আর কোনও উপায় নির্মিত হয়নি। তবে যদি আপনি কেবল লাতিন / ইউরোপীয় / সিরিলিক / গ্রীক / হিব্রু / আরবি স্ক্রিপ্টগুলি নিয়ে কাজ করে থাকেন তবে আপনার হৃদয়ের বিষয়বস্তুতে আপনি কেবল s.charAt () করুন। :)
জোনাথন ফেইনবার্গ

24
তবে আপনার উচিত হবে না। উদাহরণস্বরূপ যদি আপনার প্রোগ্রামটি এক্সএমএল আউটপুট করে এবং যদি কেউ এটিকে কিছু অস্পষ্ট গাণিতিক অপারেটর দেয়, হঠাৎ আপনার এক্সএমএল অবৈধ হতে পারে।
যান্ত্রিক শামুক 1

2
আমি ব্যবহার করতে হবে offset = s.offsetByCodePoints(offset, 1);offset += Character.charCount(codepoint);পরিবর্তে ব্যবহার করে কিছু সুবিধা আছে ?
পল গ্রোক

3
@ মেকানিক্যালসনেইল আমি আপনার মন্তব্য বুঝতে পারি না। এক্সএমএল আউটপুটিংয়ের কারণে কেন এই উত্তরটি খারাপ আচরণের কারণ হবে?
গিলি

3
@ গিলি উত্তর ভাল আছে। তিনি @ জোনাথন ফিনবার্গের মন্তব্যে উল্লেখ করেছেন যেখানে তিনি charAt()একটি খারাপ ধারণা
রিকার্সিভ এক্সপ্লেস এক্সপশন

72

জাভা 8 যুক্ত করেছে CharSequence#codePointsযা IntStreamকোড পয়েন্ট সম্বলিত একটি ফেরত দেয় । আপনি এগুলি পুনরাবৃত্তি করতে সরাসরি স্ট্রিমটি ব্যবহার করতে পারেন:

string.codePoints().forEach(c -> ...);

অথবা একটি অ্যারেতে স্ট্রিমটি সংগ্রহ করে লুপের জন্য:

for(int c : string.codePoints().toArray()){
    ...
}

এই উপায়গুলি সম্ভবত জোনাথন ফিনবার্গসের সমাধানের চেয়ে ব্যয়বহুল , তবে তারা পড়তে / লিখতে দ্রুত হয় এবং পারফরম্যান্সের পার্থক্যটি সাধারণত নগণ্য হবে।


3
for (int c : (Iterable<Integer>) () -> string.codePoints().iterator())কাজ করে।
saka1029

2
@ Saka1029 সামান্য খাটো সংস্করণ: গুলি কোড:for (int c : (Iterable<Integer>) string.codePoints()::iterator) ...
Lii

7

কোড পয়েন্টের সাথে ইটারেটিং সূর্যের বৈশিষ্ট্যের অনুরোধ হিসাবে দায়ের করা হয়েছে।

দেখুন সূর্যের বাগ এণ্ট্রি

স্ট্রিং কোডপয়েন্টগুলিতে কীভাবে পুনরাবৃত্তি করা যায় সে সম্পর্কেও একটি উদাহরণ রয়েছে।


6
জাভা 8 -এ এখন একটি কোডপয়েন্টস () পদ্ধতি রয়েছে স্ট্রিং-এ অন্তর্নির্মিত: ডকস.ওরাকল.com
ডভ ওয়াসারম্যান

7

ভেবেছিলাম আমি একটি কাজের পদ্ধতি যুক্ত করব যা ফোরচ লুপগুলি ( রেফ ) দিয়ে কাজ করে , আপনি জাভা 8 এ যাওয়ার সময় আপনি সহজেই এটি জাভা 8 এর নতুন স্ট্রিং # কোডপয়েন্ট পদ্ধতিতে রূপান্তর করতে পারেন :

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

 for(int codePoint : codePoints(myString)) {
   ....
 }

এখানে হ'ল সহায়ক মোডথ:

public static Iterable<Integer> codePoints(final String string) {
  return new Iterable<Integer>() {
    public Iterator<Integer> iterator() {
      return new Iterator<Integer>() {
        int nextIndex = 0;
        public boolean hasNext() {
          return nextIndex < string.length();
        }
        public Integer next() {
          int result = string.codePointAt(nextIndex);
          nextIndex += Character.charCount(result);
          return result;
        }
        public void remove() {
          throw new UnsupportedOperationException();
        }
      };
    }
  };
}

অথবা অন্যথায় যদি আপনি কেবল একটি স্ট্রিংকে int এর অ্যারে রূপান্তর করতে চান (যা উপরের পদ্ধতির চেয়ে বেশি র্যাম ব্যবহার করতে পারে):

 public static List<Integer> stringToCodePoints(String in) {
    if( in == null)
      throw new NullPointerException("got null");
    List<Integer> out = new ArrayList<Integer>();
    final int length = in.length();
    for (int offset = 0; offset < length; ) {
      final int codepoint = in.codePointAt(offset);
      out.add(codepoint);
      offset += Character.charCount(codepoint);
    }
    return out;
  }

কৃতজ্ঞতার সাথে "কোডপয়েন্টস" ব্যবহার করে ইউটিএফ -16 (জাভার অভ্যন্তরীণ স্ট্রিং প্রতিনিধিত্ব) এর সুরোগেট জুড়ি-নেস নিরাপদে পরিচালনা করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.