2010-09-30 40 views
5

Loại trả về của hàm zip là gì? (zip như trong hầu hết các ngôn ngữ khác, ví dụ: read here)Java: Cách viết hàm `zip`? Loại trả về là gì?

Tôi đã nghĩ về một số loại Pair nhưng không tồn tại trong Java. Nó thường nói rằng điều này là bởi vì một cặp lớp chuyên biệt là tốt hơn so với một chung (xem this câu hỏi). Tuy nhiên, điều này là không thể trong chức năng chung của zip.

+2

Có một lớp Pair. Bạn vừa viết nó. –

+0

có thể trùng lặp của [Tương đương với cặp C++ bằng Java là gì?] (Http://stackoverflow.com/questions/156275/what-is-the-equivalent-of-the-c-pairl-r-in -java) –

+0

Tại sao MAP không hoạt động? Nó sẽ lưu trữ các cặp khóa, giá trị và tôi đã thực hiện các khóa dựa trên đối tượng. – jim

Trả lời

7

Vì bạn dường như được xác định để bỏ qua những người có nhiều năm kinh nghiệm Java, đây là mã thực hiện giống như chức năng zip trong python.

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

Prints

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

Để dịch bài đăng của bạn thành câu trả lời cho câu hỏi của tôi: Tôi chỉ có thể sử dụng 'Danh sách 'thay vì' Ghép nối '. Vẫn không làm việc mặc dù nếu tôi muốn 'zip' danh sách các loại khác nhau. – Albert

+0

Tất cả các loại mở rộng Object và bạn có thể sử dụng nó cho tất cả các loại. –

+0

Giải pháp rất đẹp –

1

Không, không rõ ràng là một cặp (hoặc bất kỳ bộ túp nào) trong JRE chuẩn.

Có một số discussion on the subject trên nhóm Google javaposse mà bạn có thể quan tâm, liên kết tới bài đăng theo Dick Wall on why Java needs a Pair and a Triple, cộng với similar question asked here.


Cập nhật - câu hỏi ban đầu là liệu có một cặp trong Java hay không. Câu trả lời này có thể không còn ý nghĩa nữa.

0

Đây là sự bắt đầu.

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

tôi trả lời Java 'zip' qusetion hoàn toàn ra khỏi sự quan tâm và tôi làm không tư vấn giải pháp này - mà không phải là một chức năng, mặc dù bạn có thể có nó xây dựng một danh sách các danh sách nếu bạn muốn.

Có thể lặp qua hai danh sách giống nhau cho vòng lặp sử dụng như sau.

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()) { 
    ... 
} 

Đó là không một giải pháp tốt đẹp.

0

Tôi nghĩ rằng tôi đã thực hiện lớp cặp điều chỉnh gần như hoàn hảo: 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); 
    } 
} 
Các vấn đề liên quan