تعد فئة Java Hashtable واحدة من أقدم أعضاء Java Collection Framework. إنه تطبيق لبنية بيانات جدول التجزئة الرياضي. في Java، يحتوي جدول التجزئة داخليًا على مجموعات يتم فيها تخزين أزواج المفتاح/القيمة. Hashtable يشبه إلى حد كبير HashMap . الفرق الأكثر أهمية بينهما: تتم مزامنة Hashtable بينما لا تتم مزامنة HashMap .
Hashtable كبنية البيانات
Hashtable عبارة عن بنية بيانات حيث يتم تخزين البيانات بتنسيق صفيف. كل قيمة بيانات لها قيمة مفتاح فريدة. إذا كان المفتاح معروفًا، فإن الوصول إلى البيانات المطلوبة يكون سريعًا جدًا. لذلك، تكون عمليات الإدراج والبحث سريعة بشكل مستقل عن حجم البيانات. يتكون جدول التجزئة من مصفوفة للاحتفاظ بالبيانات والتجزئة لإنشاء فهرس حيث يجب أن يوجد العنصر. ما هو التجزئة؟ إنها قاعدة تقوم بتعيين الكائن إلى مجموعة من الأحرف (الرمز). عادةً ما يقوم هذا النوع من الوظائف بتحويل جزء كبير من البيانات إلى قيمة عددية صغيرة. يمكن أن تكون دوال التجزئة مختلفة، ولكنها جميعها تقدم خصائص معينة:- كائن معين لديه رمز التجزئة المحدد.
- كائنان متساويان لهما نفس رموز التجزئة. والعكس ليس صحيحا.
- إذا كان اثنان من رموز التجزئة مختلفة، فإن الكائنات ليست متساوية بالتأكيد.
- قد تحتوي الكائنات المختلفة على نفس رمز التجزئة. هذا الحدث النادر جدًا يدعو إلى الاصطدام. تعمل وظيفة التجزئة الجيدة على تقليل احتمالية الاصطدامات.
جدول التجزئة في جافا
فئة Hashtable هي تنفيذ بنية بيانات جدول التجزئة. تم إنشاء هذه المجموعة في وقت سابق لـ Java Collection Framework، ولكن تم تضمينها فيها لاحقًا. مثل جميع المجموعات "المبكرة" (من Java 1.0)، تتم مزامنة جدول التجزئة (يتم وضع علامة على جميع الأساليب تقريبًا على أنها متزامنة). وبسبب هذا العامل، يواجه جدول التجزئة مشكلات كبيرة في الأداء. ومن ثم، بدءًا من Java 1.2، يوصى في معظم الحالات باستخدام تطبيقات أخرى لواجهة الخريطة بسبب افتقارها إلى المزامنة. عادةً ما يكون HashMap هو البديل الأنسب. لذا فإن Class Hashtable<K,V> يتكون من مفاتيح وقيم. يقوم بتخزين المفاتيح على مبدأ التجزئة. يتم تخزين أزواج القيمة الرئيسية في "دلاء". تقوم الدلاء معًا ببناء "جدول"، وهو نوع من المصفوفة الداخلية. يستخدم Hashtable رمز التجزئة الخاص بالمفتاح لتحديد المجموعة التي يجب تعيين زوج المفتاح/القيمة فيها. تتيح وظيفة التجزئة الحصول على موقع الجرافة من رمز التجزئة الخاص بالمفتاح. ترجع هذه الدالة رقمًا صحيحًا لكائن ما. كما قلنا أعلاه، فإن كائنين متساويين لهما نفس رمز التجزئة، في حين أن كائنين غير متساويين قد لا يكون لهما دائمًا رموز تجزئة مختلفة. قد تحتوي الكائنات المختلفة الموضوعة في جدول التجزئة على نفس رمز التجزئة. لحل هذه المشكلة (التصادم) يتم استخدام مجموعة من القوائم في جدول التجزئة. يتم تخزين الأزواج المعينة لمجموعة واحدة في قائمة ويتم تخزين مرجع القائمة هذا في فهرس المصفوفة.منشئو جافا Hashtable
- Hashtable() ، المنشئ الافتراضي. يقوم بإنشاء جدول تجزئة فارغ. (السعة الأولية الافتراضية = 11، عامل الحمولة = 0.75).
- يقوم Hashtable(int size) بإنشاء جدول تجزئة بالحجم المحدد.
- يقوم Hashtable(int size, float fillRatio) بإنشاء جدول تجزئة بالحجم المحدد ونسبة التعبئة.
- يقوم Hashtable(Map m) بإنشاء جدول تجزئة بنفس التعيينات مثل الخريطة المحددة.
إعلان Hashtable
تطبق فئة Hashtable Java واجهات Map و Cloneable و Serializable . يمتد فئة القاموس .Hashtable.java
public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, java.io.Serializable
K هو نوع المفاتيح التي تحتفظ بها الخريطة. V هو نوع القيم المعينة. مثال:
Hashtable<Student, Integer> myHTable = new Hashtable<>();
كيفية استيراد جافا قابل للتجزئة
Java Hashtable موجود داخل حزمة java.util . لذا استخدم import java.util.Hashtable; في التعليمات البرمجية الخاصة بك. عادة سوف تحصل على تلميح من IDE الخاص بك حول هذا الموضوع.العمليات الرئيسية Hashtable
العمليات الرئيسية لـ Hashtable هي الحصول على المجموعة وإدراجها وإزالتها من هناك. وهذه العمليات الثلاث هي:- يقوم الحصول على الكائن (مفتاح الكائن) بإرجاع قيمة الكائن الذي يحتوي على المفتاح المحدد. يُرجع قيمة فارغة إذا لم يتم العثور على مثل هذا المفتاح.
- يقوم وضع الكائن (مفتاح الكائن، قيمة الكائن) بتعيين المفتاح المحدد إلى القيمة المحددة. لا يمكن أن يكون المفتاح أو القيمة فارغة.
- int size() يُرجع كمية الإدخالات في جدول التجزئة.
- تحتوي القيمة المنطقية على (قيمة الكائن) للتحقق مما إذا كانت القيمة المحددة موجودة في جدول التجزئة. إذا كان الأمر كذلك، فإن الطريقة تُرجع صحيحًا، وإلا تُرجع خطأ.
- منطقية تحتوي على قيمة (قيمة الكائن) تتحقق مما إذا كانت القيمة المحددة موجودة في جدول التجزئة. إذا كان الأمر كذلك، فإن الطريقة تُرجع صحيحًا، وإلا تُرجع خطأ.
- يزيل void Clear() جميع الإدخالات من جدول التجزئة.
- تحتوي القيمة المنطقية على مفتاح (مفتاح الكائن) على إرجاع صحيح إذا كان المفتاح المحدد موجودًا في جدول التجزئة، وإلا فسيتم إرجاع خطأ.
- boolean isEmpty() يُرجع صحيحًا إذا كان جدول التجزئة فارغًا أو خطأ إذا كان يحتوي على مفتاح واحد على الأقل.
- تعمل وظيفة void rehash() على زيادة حجم جدول التجزئة وإعادة صياغة جميع مفاتيحه.
تنفيذ جدول التجزئة، كود جافا:
لنقم بإنشاء فصل دراسي للطلاب :import java.util.Date;
public class Student {
String surname;
String name;
String secondName;
Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases
public Student(String surname, String name, String secondName, Date birthday ){
this.surname = surname;
this.name = name;
this.secondName = secondName;
this.birthday = birthday == null ? 0 : birthday.getTime();
}
@Override
public int hashCode(){
//TODO: check for nulls
return (surname + name + secondName + birthday).hashCode();
}
@Override
public boolean equals(Object other_) {
Student other = (Student)other_;
return (surname == null || surname.equals(other.surname) )
&& (name == null || name.equals(other.name))
&& (secondName == null || secondName.equals(other.secondName))
&& (birthday == null || birthday.equals(other.birthday));
}
}
هنا مثال جافا Hashtable . دعونا نضع كائنين من فئة الطالب في جدول التجزئة، ثم نزيل بعضًا منهما ونتحقق من بعض المعلمات.
public class HashTableExample {
public static void main(String[] args) {
Hashtable<Student, Integer> myHTable = new Hashtable<>();
Student sarah1 = new Student("Sarah","Connor", "Jane", null);
Student john = new Student("John","Connor", "Kyle", new Date(1985, 02-1, 28)); // date not exists
myHTable.put(john,1);
myHTable.put(sarah1,0);
System.out.println(myHTable.get(john));
System.out.println(myHTable.isEmpty());
System.out.println(myHTable.size());
System.out.println(myHTable.contains(1));
myHTable.remove(john);
System.out.println(myHTable.contains(0));
System.out.println(myHTable.contains(1));
System.out.println(myHTable.containsKey(sarah1));
}
}
نتيجة تشغيل البرنامج هي:
1
false
2
true
true
false
true
HashMap مقابل Hashtable
- يشبه Hashtable HashMap في Java. الفرق الأكثر أهمية هو أن Hashtable متزامن بينما HashMap ليس كذلك. ولذلك، فإن Hashtable أبطأ من HashMap بسبب المزامنة.
- باستثناء مشكلة المزامنة، لا يسمح Hashtable باستخدام القيمة الخالية كقيمة أو مفتاح. يسمح HashMap بمفتاح فارغ واحد وقيم فارغة متعددة.
- يرث Hashtable فئة القاموس بينما يرث HashMap فئة AbstractMap.
- يتم اجتياز HashMap بواسطة Iterator. يمكن اجتياز Hashtable ليس فقط عن طريق Iterator ولكن أيضًا عن طريق Enumerator.
مثال Java قابل للتجزئة (Hashtable vs HashMap null key)
إليك رمز الجزء لتوضيح القيمة الخالية المستخدمة كمفتاح وقيمة في HashMap و Hashtable// Null key Java hashtable example and hashmap example
try{
System.out.println("Hashtable");
Hashtable hashTable = new Hashtable();
hashTable.put(null, new Object());
}catch(Exception ex){
ex.printStackTrace();
}
System.out.println("HashMap");
HashMap hashMap = new HashMap();
hashMap.put(null, new Object());
System.out.println("as you see no exceptions with null key in HashMap");
}
نتيجة تشغيل البرنامج الذي يحتوي على هذا الجزء:
java.lang.NullPointerException
at java.base/java.util.Hashtable.put(Hashtable.java:480)
at Character.main(Character.java:58)
HashMap
as you see no exceptions with null key in HashMap
GO TO FULL VERSION