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


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.