kolekcje i 2 klucze

kolekcje i 2 klucze
MI
  • Rejestracja: dni
  • Ostatnio: dni
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

Koziołek
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Stacktrace
  • Postów: 6823
0

Problem z serii klasycznych :D

Kopiuj
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.

MI
  • Rejestracja: dni
  • Ostatnio: dni
0

nie rozumiem :( moglbys skomentowac zalozenia?

Koziołek
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Stacktrace
  • Postów: 6823
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.

MI
  • Rejestracja: dni
  • Ostatnio: dni
0

;((

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

Kopiuj
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:

Kopiuj
 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:

Kopiuj
 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.

Koziołek
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Stacktrace
  • Postów: 6823
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.

Kopiuj
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);
	}
}
MI
  • Rejestracja: dni
  • Ostatnio: dni
0

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

Kopiuj
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));
   }
}
Kopiuj
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

Koziołek
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Stacktrace
  • Postów: 6823
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:

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

i odpowiednio rozbudować metodę equals.

MI
  • Rejestracja: dni
  • Ostatnio: dni
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:

Kopiuj
   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

Koziołek
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Stacktrace
  • Postów: 6823
0

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

MI
  • Rejestracja: dni
  • Ostatnio: dni
0
Kopiuj
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:

Kopiuj
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);
   }
}
Freakman
  • Rejestracja: dni
  • Ostatnio: dni
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.

MI
  • Rejestracja: dni
  • Ostatnio: dni
0

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

Koziołek
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Stacktrace
  • Postów: 6823
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.

Freakman
  • Rejestracja: dni
  • Ostatnio: dni
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 ; ) )

MI
  • Rejestracja: dni
  • Ostatnio: dni
0

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

Kopiuj
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?

Koziołek
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Stacktrace
  • Postów: 6823
0

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

MI
  • Rejestracja: dni
  • Ostatnio: dni
0

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

Kopiuj
   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:

Kopiuj
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:

Kopiuj
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..

MI
  • Rejestracja: dni
  • Ostatnio: dni
0

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

Kopiuj
   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!!

MI
  • Rejestracja: dni
  • Ostatnio: dni
0

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

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.