2011-09-16 28 views
7

Tôi muốn áp dụng một chức năng cho một bộ sưu tập, bản đồ, vv, bằng cách sử dụng ổi.Có thể áp dụng một chức năng cho một bộ sưu tập bằng cách sử dụng Java ổi không?

Về cơ bản, tôi cần phải thay đổi kích thước hàng và cột của một Table riêng vì vậy tất cả các hàng và cột có kích thước bằng nhau, làm một cái gì đó như thế này:

Table<Integer, Integer, Cell> table = HashBasedTable.create(); 
    Maps.transformValues(table.columnMap(), new ResizeFunction(BlockDimension.WIDTH)); 
    Maps.transformValues(table.rowMap(), new ResizeFunction(BlockDimension.HEIGHT)); 

public interface Cell { 
    int getSize(BlockDimension dimension); 
    void setSize(BlockDimension dimension); 
} 

Tôi đã có một ý tưởng về những gì ResizeFunction nên được. Tuy nhiên, tôi cần phải áp dụng, không chỉ trả lại Collection.

Trả lời

13

Trong ổi, bạn không chuyển đổi Chức năng hiện có, nhưng thay vì tạo một hình mới sử dụng Iterables.transform:

final List<String> list = Arrays.asList("race", "box"); 
final List<String> transformed = 
    Lists.newArrayList(Iterables.transform(list, new Function<String, String>() { 

     @Override 
     public String apply(final String input) { 
      return new StringBuilder().append(input).append("car").toString(); 
     } 
    })); 
System.out.println(transformed); 

Output:

[xe đua, toa chở súc vật]

Hoặc nếu bạn không cần ListCollection sẽ làm, bạn có thể sử dụng chế độ xem trực tiếp được chuyển đổi:

final Collection<String> transformed = 
    Collections2.transform(list, new Function<String, String>() { 

     @Override 
     public String apply(final String input) { 
      return new StringBuilder().append(input).append("car").toString(); 
     } 
    }); 

này Collection là một cái nhìn trực tiếp của cơ bản một, vì vậy thay đổi list sẽ được phản ánh trong Collection này.

+0

Xin lỗi tôi không rõ ràng về bản chất của vấn đề (xem ở trên). Như bạn thấy, tôi cần áp dụng hàm này cho các tập hợp hàng + cột và tôi không muốn trả lại chúng. –

+0

Tôi chấp nhận vì điều này là chính xác, mặc dù tôi vẫn cho rằng ổi nên có hàm apply() ngay lập tức áp dụng cho bộ sưu tập. –

3

gì về việc tạo ra một chức năng như thế này:

public static <T> void apply(Iterable<T> iterable, Function<T, Void> function) { 
    for (T input : iterable) 
     function.apply(input); 
} 
+0

Tôi sẽ đặt tên cho phương thức 'applyToEach'. Và bạn có thể sử dụng 'Function ' làm kiểu tham số, điều này cho phép sử dụng các hàm có giá trị trả về, trong đó bạn không quan tâm. –

0

Tôi nghĩ sẽ sẽ khấm khá hơn thiết lập bảng trước khi dân số là kích thước phù hợp/có số lượng thích hợp của các tế bào ngay cả khi họ đang có sản phẩm nào. Một cái gì đó như:

for (int i=0; i<numRows; i++) 
    for (int j=0; j<numColumns; j++) 
     table.put(i,j,null); 

Điều này sẽ đảm bảo có một ô cho từng vị trí trong bảng của bạn. Vì vậy, miễn là bạn chỉ thêm các ô vào các hàng, các vị trí cột nằm trong vòng numRows, các cột numColumn bạn sẽ giữ một bảng "hình vuông".

1

Sean đã đề cập rằng ổi không thay đổi bộ sưu tập gốc, do đó bạn không thể "áp dụng" một chức năng trên bộ sưu tập hiện có của mình.

Nó không rõ ràng những gì chức năng ResizeFunction của bạn, nếu bạn chỉ thay đổi giá trị của Cell trong Table<Integer, Integer, Cell> sau đó bạn có thể sử dụng Tables#transformValues()

Ổi không cho phép bạn thay đổi các giá trị của RC trong Table<R, C, V> (trong tiêu chuẩn Tables lớp) vì chúng được sử dụng làm khóa trong khi trả về bản đồ hàng hoặc cột (Table#rowMap()Table#columnMap()) và bạn không thể chuyển đổi chúng vì tất cả các phương pháp biến đổi và lọc của Guava tạo ra kết quả lười biếng có nghĩa là hàm/vị ngữ chỉ được áp dụng khi cần thiết đối tượng được sử dụng. Họ không tạo bản sao. Do đó, mặc dù, một phép biến đổi có thể dễ dàng phá vỡ các yêu cầu của một Set.

Nếu bạn vẫn muốn làm điều đó thì bạn có thể bọc Table đối tượng trong lớp của riêng bạn và cung cấp một phương pháp được yêu cầu.

Các vấn đề liên quan