2010-09-30 46 views
5

zip函數的返回類型應該是什麼? (zip與其他大多數語言一樣,例如read hereJava:如何編寫`zip`函數?什麼應該是返回類型?

我想到了一些Pair類型,但在Java中不存在。通常情況下,這是因爲一個專門的Pair-Class比一般的更好(參見this問題)。但是,這在一般的zip函數中是不可能的。

+2

有一雙類。你只是寫了它。 – 2010-09-30 18:50:34

+0

[Java中的C++ Pair 的等效物是什麼?](http://stackoverflow.com/questions/156275/what-is-the-equivalent-of-the-c-pairl-r-in -java) – 2010-09-30 18:51:29

+0

爲什麼不能使用MAP?它將存儲鍵和值對,並且我已經完成了基於對象的鍵。 – jim 2010-09-30 18:52:16

回答

7

由於您似乎決定忽略具有多年Java經驗的人,因此這裏的代碼與python中的zip函數的作用相同。

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 '。儘管如果我想'壓縮'不同類型的列表仍然無法正常工作。 – Albert 2010-10-10 02:40:46

+0

所有類型都擴展Object,並且您可以將其用於所有類型。 – 2010-10-12 20:59:56

+0

非常好的解決方案 – 2014-03-25 10:29:25

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純粹是出於興趣,我做告知解決方案 - 這是不是一個功能,但你可以有它會建立一個列表,如果你喜歡。

使用以下代碼可以在同一個for循環中迭代兩個列表。

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