2010-09-30 3 views
5

Какой должен быть тип возврата функции zip? (zip, как на большинстве других языков, например read here)Java: Как написать функцию `zip`? Каким должен быть тип возврата?

Я думал о некоторых типах пар, но не существует на Java. Часто говорится, что это связано с тем, что специализированный класс Pair лучше, чем общий (см. Вопрос this). Однако это невозможно в общей функции zip.

+2

Существует класс Pair. Вы только что написали это. –

+0

Возможный дубликат [Что эквивалентно C++ Pair в Java?] (Http://stackoverflow.com/questions/156275/what-is-the-equivalent-of-the-c-pairl-r-in -java) –

+0

Почему MAP не работает? Он будет хранить пары ключей, значений и я делаю ключи на основе объектов. – jim

ответ

7

Так как вы, кажется, решил игнорировать человек со многим опытом лет Java, вот код, который делает то же самое, что и функция почтового индекса в питоне.

public static <T> List<List<T>> zip(List<T>... lists) { 
    List<List<T>> zipped = new ArrayList<List<T>>(); 
    for (List<T> list : lists) { 
     for (int i = 0, listSize = list.size(); i < listSize; i++) { 
      List<T> list2; 
      if (i >= zipped.size()) 
       zipped.add(list2 = new ArrayList<T>()); 
      else 
       list2 = zipped.get(i); 
      list2.add(list.get(i)); 
     } 
    } 
    return zipped; 
} 

public static void main(String[] args) { 
     List<Integer> x = Arrays.asList(1, 2, 3); 
     List<Integer> y = Arrays.asList(4, 5, 6); 
     List<List<Integer>> zipped = zip(x, y); 
     System.out.println(zipped); 
} 

Печать

[[1, 4], [2, 5], [3, 6]] 
+0

Чтобы перевести ваше сообщение в ответ на мой вопрос: я могу просто использовать 'List ' вместо 'Pair '. Все еще не работает, хотя если я хочу 'zip' списки разных типов. – Albert

+0

Все типы расширяют объект, и вы можете использовать его для всех типов. –

+0

Очень приятное решение –

1

Нет, в стандартной JRE явно нет пары (или любого кортежа).

В группе javaposse Google, которая вас может заинтересовать, был discussion on the subject, который ссылается на сообщение Dick Wall on why Java needs a Pair and a Triple, а также similar question asked here.

Обновление - исходный вопрос состоял в том, была ли пара в Java. Этот ответ больше не имеет смысла.

0

Это старт.

public class Pair<T1, T2> 
{ 
    private T1 first; 
    private T2 second; 

    public Pair(T1 first, T2 second) 
    { 
     this.first = first; 
     this.second = second; 
    } 

    public T1 getFirst() 
    { 
     return first; 
    } 

    public T2 getSecond() 
    { 
     return second; 
    } 
} 
0

я отвечаю на Java «молния» qusetion чисто из интереса и я не посоветуете это решение - которое не является функцией, хотя вы могли бы иметь он строит список списков, если хотите.

Можно перебрать два списка в одном и том же цикле, используя следующее.

Iterator<Object> iterA=listA.iterator(); 
Iterator<Object> iterB=listB.iterator(); 
for (Object a=iterA.next(), b=iterB.next(); 
    iterA.hasNext()&&iterB.hasNext(); 
    a=iterA.next(), b=iterB.next()) { 
    ... 
} 

Это не хорошее решение.

0

Я думаю, что я сделал пару класса настроенный почти до совершенства: P

public class Pair<T1, T2> implements Iterable<Object>, Cloneable{ 

    public static <X, Y> Pair<X, Y> makePair(X x, Y y){ 
     return new Pair<X, Y>(x, y); 
    } 

    public static <X> Pair<X, X[]> makePairFromArray(X... xs){ 
     if (xs.length == 0) 
      return new Pair<X, X[]>(null, null); 
     if (xs.length == 1) 
      return new Pair<X, X[]>(xs[0], null); 
     return new Pair<X, X[]>(xs[0], Arrays.copyOfRange(xs, 1, xs.length-1)); 
    } 

    public static <X, Y> Pair<X, Y> reverse(Pair<Y, X> original){ 
     return makePair(original.getSecond(), original.getFirst()); 
    } 

    public static synchronized <X> void swap(Pair<X, X> swapped){ 
     X tmp = swapped.getFirst(); 
     swapped.setFirst(swapped.getSecond()); 
     swapped.setSecond(tmp); 
    } 

    @SuppressWarnings("unchecked") 
    public static <X, Y> List<Object> asObjectList(Pair<X, Y> pair){ 
     return asList((Pair<Object, Object>) pair); 
    } 

    public static <X, Y> Object[] asObjectArray(Pair<X, Y> pair, Object[] array){ 
     return asObjectList(pair).toArray(array); 
    } 

    public static <X> List<X> asList(Pair<X, X> pair){ 
     ArrayList<X> list = new ArrayList<X>(); 
     list.add(pair.getFirst()); 
     list.add(pair.getSecond()); 
     return list; 
    } 

    public static <X> X[] asArray(Pair<X, X> pair, X[] array){ 
     return asList(pair).toArray(array); 
    } 

    public static <X> Iterator<X> typedIterator(Pair<X, X> pair){ 
     @SuppressWarnings("unchecked") 
     final Iterator<X> it = (Iterator<X>) pair.iterator(); 
     return it; 
    } 

    public static <X> boolean isSymmetric(Pair<X, X> pair){ 
     return pair.equals(reverse(pair)); 
    } 

    public static <X> boolean isReflexive(Pair<X, X> pair){ 
     X x1 = pair.getFirst(); 
     X x2 = pair.getSecond(); 

     if (x1 == null && x2 == null) return true; 
     if (x1 == null && x2 != null) return false; 
     if (x1 != null && x2 == null) return false; 
     return x1.equals(x2); 
    } 

    public static <X, Y, Z> boolean isTransitive(Pair<X, Y> first, Pair<Y, Z> second){ 
     Y y1 = first.getSecond(); 
     Y y2 = second.getFirst(); 

     if (y1 == null && y2 == null) return true; 
     if (y1 == null && y2 != null) return false; 
     if (y1 != null && y2 == null) return false; 
     return y1.equals(y2); 
    } 

    public static synchronized <X, Y> Pair<X, Y> immutablePair(Pair<X, Y> pair){ 
     final Pair<X, Y> wrapped = pair; 
     return new Pair<X, Y>(null, null){ 

      @Override 
      public X getFirst() { 
       return wrapped.getFirst(); 
      } 

      @Override 
      public Y getSecond() { 
       return wrapped.getSecond(); 
      } 

      @Override 
      public void setFirst(X first) { 
       throw new UnsupportedOperationException(); 
      } 

      @Override 
      public void setSecond(Y second) { 
       throw new UnsupportedOperationException(); 
      } 

      @Override 
      public int hashCode() { 
       return wrapped.hashCode(); 
      } 

      @Override 
      public boolean equals(Object obj) { 
       return wrapped.equals(obj); 
      } 

      @Override 
      public String toString() { 
       return wrapped.toString(); 
      } 

      @Override 
      public Iterator<Object> iterator() { 
       return wrapped.iterator(); 
      } 

      @Override 
      public Object clone() throws CloneNotSupportedException { 
       return wrapped.clone(); 
      } 

      @Override 
      public Pair<X, Y> copy() { 
       return wrapped.copy(); 
      } 

     }; 
    } 

    public static synchronized <X, Y> Pair<X, Y> synchronizedPair(Pair<X, Y> pair){ 
     final Pair<X, Y> wrapped = pair; 
     return new Pair<X, Y>(null, null){ 

      @Override 
      public synchronized X getFirst() { 
       return wrapped.getFirst(); 
      } 

      @Override 
      public synchronized void setFirst(X first) { 
       wrapped.setFirst(first); 
      } 

      @Override 
      public synchronized Y getSecond() { 
       return wrapped.getSecond(); 
      } 

      @Override 
      public synchronized void setSecond(Y second) { 
       wrapped.setSecond(second); 
      } 

      @Override 
      public synchronized int hashCode() { 
       return wrapped.hashCode(); 
      } 

      @Override 
      public synchronized boolean equals(Object obj) { 
       return wrapped.equals(obj); 
      } 

      @Override 
      public synchronized String toString() { 
       return wrapped.toString(); 
      } 

      @Override 
      public synchronized Iterator<Object> iterator() { 
       return wrapped.iterator(); 
      } 

      @Override 
      public synchronized Object clone() throws CloneNotSupportedException { 
       return wrapped.clone(); 
      } 

      @Override 
      public synchronized Pair<X, Y> copy() { 
       return wrapped.copy(); 
      } 

     }; 
    } 

    public Pair(T1 first, T2 second) { 
     super(); 
     this.first = first; 
     this.second = second; 
    } 

    public Pair(){ 
     super(); 
     this.first = null; 
     this.second = null; 
    } 

    public Pair(Pair<T1, T2> copy) { 
     first = copy.first; 
     second = copy.second; 
    } 

    private T1 first; 
    private T2 second; 

    public T1 getFirst() { 
     return first; 
    } 

    public void setFirst(T1 first) { 
     this.first = first; 
    } 

    public T2 getSecond() { 
     return second; 
    } 

    public void setSecond(T2 second) { 
     this.second = second; 
    } 

    @Override 
    public int hashCode() { 
     final int prime = 31; 
     int result = 1; 
     result = prime * result + ((first == null) ? 0 : first.hashCode()); 
     result = prime * result + ((second == null) ? 0 : second.hashCode()); 
     return result; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     if (this == obj) 
      return true; 
     if (obj == null) 
      return false; 
     if (getClass() != obj.getClass()) 
      return false; 
     @SuppressWarnings("rawtypes") 
     Pair other = (Pair) obj; 
     if (first == null) { 
      if (other.first != null) 
       return false; 
     } else if (!first.equals(other.first)) 
      return false; 
     if (second == null) { 
      if (other.second != null) 
       return false; 
     } else if (!second.equals(other.second)) 
      return false; 
     return true; 
    } 

    @Override 
    public String toString() { 
     return "(" + first + ", " + second + ")"; 
    } 

    @Override 
    public Iterator<Object> iterator() { 
     return new Iterator<Object>(){ 
      private int it = 0; 

      @Override 
      public boolean hasNext() { 
       return it != 2; 
      } 

      @Override 
      public Object next() { 
       return (it++) == 0 ? first : second; 
      } 

      @Override 
      public void remove() { 
       throw new UnsupportedOperationException(); 
      } 

     }; 
    } 

    @Override 
    public Object clone() throws CloneNotSupportedException { 
     return super.clone(); 
    } 

    public Pair<T1, T2> copy(){ 
     return makePair(first, second); 
    } 
} 
Смежные вопросы