【问题标题】:Java: How to write a `zip` function? What should be the return type?Java:如何编写“zip”函数?返回类型应该是什么?
【发布时间】:2010-09-30 18:49:24
【问题描述】:

zip 函数的返回类型应该是什么? (zip 与大多数其他语言一样,例如read here

我想到了一些 Pair 类型,但在 Java 中不存在。通常情况下,这是因为专门的 Pair 类比一般的 Pair 类更好(请参阅this 问题)。但是,这在一般的zip 函数中是不可能的。

【问题讨论】:

  • 有一个 Pair 类。你刚刚写的。
  • 为什么 MAP 不起作用?它将存储键、值对,我已经完成了基于对象的键。
  • @jim:你的意思是Collections.singletonMap?是的,这有效,但它是不可变的。 :-)
  • 那么Map.Entry 怎么样?那只是……半不可变的;)说真的,只要写一个 Pair 类。

标签: java


【解决方案1】:

由于您似乎决心忽略具有多年 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]]

【讨论】:

  • 将您的帖子翻译成我的问题的答案:我可以使用List&lt;T&gt; 而不是Pair&lt;T,T&gt;。如果我想zip 不同类型的列表仍然不起作用。
  • 所有类型都扩展了 Object,你可以将它用于所有类型。
【解决方案2】:

不,标准 JRE 中没有明确的一对(或任何元组)。

您可能感兴趣的 javaposse Google 群组中有一个 discussion on the subject,它链接到 Dick Wall on why Java needs a Pair and a Triple 的帖子,外加一个 similar question asked here


更新 - 最初的问题是 Java 中是否存在 Pair。这个答案可能不再有意义。

【讨论】:

    【解决方案3】:

    我回答 Java 'zip' 问题纯粹是出于兴趣,我确实建议这个解决方案 - 这不是一个函数,尽管你可以构建它如果您愿意,可以列出列表。

    可以使用以下方法在同一个 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()) {
       ...
    }
    

    不是一个不错的解决方案。

    【讨论】:

      【解决方案4】:

      这是一个开始。

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

      【讨论】:

        【解决方案5】:

        我想我已经把pair class调得几乎完美了: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);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-12-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-24
          • 1970-01-01
          • 1970-01-01
          • 2013-06-08
          相关资源
          最近更新 更多