kolekcje i 2 klucze

0

hej, mam problem z wymyslniem i zaimplementowaniem obiektu ktory trzymalby mi pare kluczy i wartosc. tzn normalnie, np w mapie jest klucz-wartosc.

ja jednak potrzbuje obiektu ktory bedzie mial:

klucz1 - klucz2 - wartosc

i potem beda miala w programie mojKlucz i bede sprawdzala po kolei czy
klucz1<= mojKlucz <= klucz2 -> jesli tak->pobierz wartosc, jesli nie-przejdz do nastepnego wiersza i tam sprawdz

jak moge cos takiego zaimplementowac? tzn obiekt klucz1 - klucz2 - wartosc?

bede wdzieczna za wszystkie sugestie,
pzdr,
misty

0

Problem z serii klasycznych :D

class A{

	Object k1,k2;
	Object v;

	@Override
	public boolean equals(Object obj) {
		if(obj instanceof A){
			A o = (A)obj;
			return k1.equals(o.k1) && k2.equals(o.k2);
		}
		return false;
	}

}

class B{

	Key k;
	Object v;

	static class Key{

		Object k1,k2;

		@Override
		public boolean equals(Object obj) {
			if(obj instanceof Key){
				Key o = (Key)obj;
				return k1.equals(o.k1) && k2.equals(o.k2);
			}
			return false;
		}
	}

	@Override
	public boolean equals(Object obj) {
		if(obj instanceof B){
			B o = (B)obj;
			return k.equals(o);
		}
		return false;
	}

}

Implementacja bardzo pobieżna. Klucz złożony jest nową klasą wewnętrzną dla klasy obiektu.

0

nie rozumiem :( moglbys skomentowac zalozenia?

0

Jeżeli masz obiekt, który ma klucz złożony to znaczy "logiczny klucz" jest złożony z więcej niż jednego obiektu to prawidłowym podejściem jest stworzenie klasy reprezentującej klucz. Obiekt posiada w takim momencie pole klucz klasy Klucz, a nie kilka prostych pól traktowanych razem jako klucz.
Takie rozwiązanie ułatwia tworzenie np. metody equals czy compareTo oraz ich testowanie.

Przykładowo klasa A ma "klucz logiczny" złożony z dwóch pól k1 i k2. Wszędzie gdzie będziesz wykorzystywać taki klucz musisz użyć obu pól. Logika działania na kluczu staje się skomplikowana ponieważ nie można pominąć żadnego z pól.
Klasa B przeniosła klucz do oddzielnej klasy wewnętrznej co pozwoliło na uproszczenie logiki działania klasy B wszędzie tam gdzie wykorzystywany jest klucz. Po prostu używane jest jedno pole, które zamyka w sobie całą logikę potrzebną do operowania na złożonych wartościach.

0

;((

przyznam ze opornie to moja glowa ogarnia. Wiec tak, tworze klase Klucz, np:

public class Klucz{
   
  private int klucz1;
private int klucz2;

  public Klucz(int k1,int k2){

         klucz1 = k1;
         klucz2 = k2;
}

}

czyli obiekt Klucz, ma 2 klucze podane przeze mnie. ale jak ja je teraz tak na prawde mam porownac? przykladowo, stworze pozniej:

 Klucz mojKlucz1 = new Klucz(22, 27);
 Klucz mojKlucz2 = new Klucz(30, 34);

HashMap hm = new HashMap();
hm.put(mojKlucz1, 10);
hm.put(mojKlucz2, 20);

i pozniej, dalej gdzies w programie, musze sprawdzic jaka wartosc zwroci mi 31. czyli musze sprawdzic czy 31 miesci sie w zakresie mojKlucz1 czy mojKlucz2.

czy metoda equals w Klucz powinna robic cos takiego:

 equals boolean(Object obj){
     //obj bedzie tym wlasnie 31
    if (klucz1<= 31 <=klucz2){
             return true;
}  else{
       return false;
}
}

czy to jest wlasciwy tok mojego biednego rozumowania? czy musze tylko (albo az) nadpisac equals z klasy Klucz?

Klucz nie moze byc klasa wewnetrzna, bede tego potrzebowac w wielu innych klasach.

0

takie buty... jak ciągle myślałem o kluczu jako o takim identyfikatorze obiektu. Tu chcesz zrobić sobie coś co będzie przechowywać pewną wartość - zakres i następnie sprawdzać w programie czy jakieś dane podane z zewnątrz mieszczą się w tym zakresie.

class Zakres {

	private final int MIN;

	private final int MAX;

	public Zakres(int mIN, int mAX) {
		super();
		MIN = mIN;
		MAX = mAX;
	}

	public boolean czyWZakresie(int i) {
		return (MIN <= i) && (i < MAX);
	}
}
0

hmm, nadal cos nie tak. machnelam na szybkiego (i bardzo byle jak):

public class Test2 {

   public static void main(String[] args) {

      HashMap hm = new HashMap();
      Klucz k1 = new Klucz(23,27);
      Klucz k2 = new Klucz(31,34);

      hm.put(k1, "10");
      hm.put(k2, "20");

      System.out.println(hm.get(23));
   }
}
public class Klucz {


   private final int MIN;
   private final int MAX;

   public Klucz(int mIN, int mAX) {
      super();
      MIN = mIN;
      MAX = mAX;
   }

   public boolean equals(Object o) {
      int i = Integer.parseInt(o.toString());
      return (MIN <= i) && (i < MAX);
   }
}

no i System.out.println(hm.get(23)); zwraca mi null. a przeciez powinien zwrocic '10' bo 23 miesci sie w zakresie klucz1

hm, bo on w sumie nie wchodzi do metody equals klasy Klucz

0

bo w get w HashMap jest sprawdzane czy klasy klucza i argumentu się zgadzają i jak się nie zgadzają to od razu leci null.

lepiej:

hm.get(new Key(23,23));

i odpowiednio rozbudować metodę equals.

0

chyba dalej bede Ci dziure wiercic. dobra-Hashmap sprawdza czy klasa klucza i argumentu sie zgadzaja, zatem jesli podam:
"hm.get(new Klucz(23,23));"

to powinien mi juz wejsc do equals Klucza tak? a nie wchodzi. equals w Klucz nadal mam:

   public boolean equals(Object o) {
      System.out.println("jestem");
      int i = Integer.parseInt(o.toString());
      System.out.println(i);
      return (MIN <= i) && (i < MAX);
   }

czyli-co by sie pozniej nie dzialo, powinien mi chociaz wypisac 'jestem'. a nie wypisuje-dostaje nulla

0

Podeślij pełen kod... bo nie mam ogarnięcia do pisania tego teraz z palca.

0
public class Test2 {

   public static void main(String[] args) {

      HashMap hm = new HashMap();
      Klucz k1 = new Klucz(23,27);
      Klucz k2 = new Klucz(31,34);

      hm.put(k1, "10");
      hm.put(k2, "20");

System.out.println(hm.get(new Klucz(23,23)));
   }
}

oraz Klucz:

public class Klucz {


   private final int MIN;
   private final int MAX;

   public Klucz(int mIN, int mAX) {
      super();

      MIN = mIN;
      MAX = mAX;
   }

   public boolean equals(Object o) {
      System.out.println("jestem");
      int i = Integer.parseInt(o.toString());
      System.out.println(i);
      return (MIN <= i) && (i < MAX);
   }
}
0

hmm może muszę sobie odświeżyć wiedzę, ale czy metoda equals biorąc object w tym przypadku nie bierze klasy Klucz??
Wydaje mi sie, że equals porównuje klucze a nie wartości.

0

hmm, moze i masz racje. ale to jak ja mam zrobic wtedy to porownanie kluczy? ze 23 miesci sie w zakresie klucz1?

0

Nie to... ale ze mnie debil... Szanowni państwo HashMap, porównuje hashCode.

Misty, niestety musisz popełnić zbrodnię na kodzie napisać metodę hashcode, która będzie zawsze zwracać 1. Względnie szukamy innego rozwiązania.

0

ogólnie to chyba zawsze jest porownywany hashcode (szukanie worka) a jak zostanie znaleziony to wtedy equals (szukanie eleemntu w danym worku)

( ogolnie to sie pisze w tej javie... a wystarczy troche danego tematu nie tykać i skleroza dopada człowieka ; ) )

0

czekaj, czekaj. samo nadpisanie hashCode az tak duzo nie da. equals tez trzeba przerobic:

public class Klucz {


   private final int MIN;
   private final int MAX;

   public Klucz(int mIN, int mAX) {
      super();
      MIN = mIN;
      MAX = mAX;

      System.out.println(mIN);
   }


   public int hashCode(){
      System.out.println("jestem hash");
      return 1;
   }
   public boolean equals(Object o) {

      if(o instanceof Klucz){
         Klucz k = (Klucz)o;
      }
return true; //wlasnie i co tu??
   }
}

no i co w tym equals-wchodzi mi tu, Klucz(23,23) jest instancja Klucza, wszystko pieknie. ale jak ja mam teraz porownac czy 23 miesci sie w zakresie klucz1 co jest w hashMapie?

0

@misty, pokombinuj troszkę. Jak sprawdzić czy dany zbiór zawiera się w innym ;) Napisz sobie na kartce.

0

nie no takie proste to napisalam sobie ale dziala tylko dla wartosci skrajnych:

   public boolean equals(Object o) {

      boolean state = false;

      if(o instanceof Klucz){
         Klucz k = (Klucz)o;
         System.out.println("k.MIN "+k.MIN);
         System.out.println("this.MIN "+this.MIN);
         System.out.println("this.MAX "+k.MAX);
         if((k.MIN >= this.MAX) && (k.MIN <= this.MAX)){
            state = true;
         }
      }
return state;
    }

no i np dla System.out.println(hm.get(new Klucz(31,31))); dostane 20, czyli ok, zas dla System.out.println(hm.get(new Klucz(23,23))); dostane 10. ale jak juz wezme sobie wartosci srodkowe np: System.out.println(hm.get(new Klucz(32,32))); to lipa, null.
Wypisalam sobie co tam sie pokolei tworzy w tym equals i jakas kaszana:

public class Test2 {

   public static void main(String[] args) {

      HashMap hm = new HashMap();
      Klucz k1 = new Klucz(23,27);
      Klucz k2 = new Klucz(31,34);

      hm.put(k1, "10");
      hm.put(k2, "20");

System.out.println(hm.get(new Klucz(32,32)));
   }
}

przy takim equals jak podalam dostane:

k.MIN 23
this.MIN 31
this.MAX 27
k.MIN 31
this.MIN 32
this.MAX 34
k.MIN 23
this.MIN 32
this.MAX 27
null

to bez sensu, wartosci sie mieszaja :/ albo sie nie mieszaja, bo przeciez this mi zwroci to aktualnego obiektu. wiec-no jak w tym equals dobrac sie do wartosci MIN/MAX z klucza?

jeju, mam nadz ze pisze jeszcze w miare logicznie..

0

dobra, sama sie juz zamotalam. mam equals co dziala:

   public boolean equals(Object o) {

      boolean state = false;

      if(o instanceof Klucz){
         Klucz k = (Klucz)o;
         if(k.MIN == this.MIN && k.MAX == this.MAX){
            return true;
         }else{

         if((this.MIN >= k.MIN) && (this.MIN <= k.MAX)){
            state = true;
         }
         }
      }
return state;

   }

jeszcze potestuje i dopracuje, ale juz chyba ok. dzieki wielkie za pomoc!!

0

oo, szkoda ze nie mozna plusikow dawac. milego dnia i jeszcze raz dzieki!

1 użytkowników online, w tym zalogowanych: 0, gości: 1