Monády v Javě

Mysteriozni Z.

Monády v Javě
« kdy: 09. 11. 2016, 20:18:43 »
Mám řekněme následující kód:

Kód: [Vybrat]
Files.walk(Paths.get("C:\\"))
            .map(Path::toFile)
            .filter(File::isFile)
            .forEach(file -> System.out.println(file.getAbsolutePath()));

Konkrétně mi jde o tohle: .filter(File::isFile)


Funkce File::isFile vypadá následovně:

Kód: [Vybrat]
  public boolean isFile() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkRead(path);
        }
        if (isInvalid()) {
            return false;
        }
        return ((fs.getBooleanAttributes(this) & FileSystem.BA_REGULAR) != 0);
    }

Pochopil bych, kdyby File::isFile byla staticka tridni metoda

Kód: [Vybrat]
public static boolean isFile(File file) { ... }

Potom by mi bylo jasne, jak .filter(File::isFile) funguje, tj. pres funkcni interface. Jenze funkce isFile() se musi zavolat nad instanci tridy File a ja nechapu, jak se toho da dosahnout pomoci lambd. Muzete mi to nekdo vysvetlit?

Dik


dustin

Re:Monády v Javě
« Odpověď #1 kdy: 09. 11. 2016, 20:38:44 »
Objekt třídy File do toho filtru leze z mapovací (tedy konverzní) metody map toFile.

pecrom

Re:Monády v Javě
« Odpověď #2 kdy: 09. 11. 2016, 21:12:22 »
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.

Mysteriozni Z.

Re:Monády v Javě
« Odpověď #3 kdy: 09. 11. 2016, 21:57:43 »
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.

Ano, tomu samozrejme rozumim, ale nechapu jak by to zavolalo isFile jinak, nez za pomoci reflexe. To jde nejak udelat pres lambdy?

Re:Monády v Javě
« Odpověď #4 kdy: 09. 11. 2016, 22:03:10 »
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.

Ano, tomu samozrejme rozumim, ale nechapu jak by to zavolalo isFile jinak, nez za pomoci reflexe. To jde nejak udelat pres lambdy?

Proc by to potrebovalo reflexi? Kdyz mas kolekci souboru, tak map, filter... aplikuji lambdu, ktera ma v hlavicce soubor. Je to omezena podoba typove inference a cele je to resene cmpiletime.


Mysteriozni Z.

Re:Monády v Javě
« Odpověď #5 kdy: 09. 11. 2016, 22:12:40 »
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.

Ano, tomu samozrejme rozumim, ale nechapu jak by to zavolalo isFile jinak, nez za pomoci reflexe. To jde nejak udelat pres lambdy?


Proc by to potrebovalo reflexi? Kdyz mas kolekci souboru, tak map, filter... aplikuji lambdu, ktera ma v hlavicce soubor. Je to omezena podoba typove inference a cele je to resene cmpiletime.

Mohl by jsi prosim napsat uryvek, jak to priblizne v te motode filter() vypada? Ty vis, ze se ma zavolat metoda File::isFile. Mas taky instanci tridy File, nad kterou se ma isFile zavolat. Jak to teda udelas jinak nez pomoci reflexe:

Kód: [Vybrat]
method.invoke(obj, arg1, arg2,...);

Re:Monády v Javě
« Odpověď #6 kdy: 09. 11. 2016, 22:22:17 »
presne tak, tim ze to premapujes na Stream<File>, tak pak u toho filtru muzes pouzit (File f) -> f.isFile() , nebo f -> f.isFile() NEBO File::isFile, protoze se to isFile zavola na tom prvku toho streamu.

Ano, tomu samozrejme rozumim, ale nechapu jak by to zavolalo isFile jinak, nez za pomoci reflexe. To jde nejak udelat pres lambdy?


Proc by to potrebovalo reflexi? Kdyz mas kolekci souboru, tak map, filter... aplikuji lambdu, ktera ma v hlavicce soubor. Je to omezena podoba typove inference a cele je to resene cmpiletime.

Mohl by jsi prosim napsat uryvek, jak to priblizne v te motode filter() vypada? Ty vis, ze se ma zavolat metoda File::isFile. Mas taky instanci tridy File, nad kterou se ma isFile zavolat. Jak to teda udelas jinak nez pomoci reflexe:

Kód: [Vybrat]
method.invoke(obj, arg1, arg2,...);

Java je OSS.

javaman ((

Re:Monády v Javě
« Odpověď #7 kdy: 09. 11. 2016, 22:29:16 »
Tohle nedá ani většina Java lopat, takže začátečník nemá skoro šanci bez velkého studia :D

Mysteriozni Zeli

Re:Monády v Javě
« Odpověď #8 kdy: 09. 11. 2016, 22:29:47 »
Tak bys mohl vedEt, ze si v te meTode filtr nic neprectu, protoze je to vsechno udelane pres interface.

dustin

Re:Monády v Javě
« Odpověď #9 kdy: 09. 11. 2016, 22:33:18 »
Tohle nedá ani většina Java lopat, takže začátečník nemá skoro šanci bez velkého studia :D

Ale houby, není to žádná věda. Bereš prachy, tak se taky nauč něco nového užitečného. Nebo ti na všechno dává zaměstnavatel lidi a sám nemusíš umět nic, jenom žvanit a chvástat se?

Re:Monády v Javě
« Odpověď #10 kdy: 09. 11. 2016, 22:36:26 »
Tak bys mohl vedEt, ze si v te meTode filtr nic neprectu, protoze je to vsechno udelane pres interface.

To je takovy problem se dobrat implementace? (on by ti mel stacit i ten interface, aby sis vsimnul tech generik).

http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/tip/src/share/classes/java/util/stream/ReferencePipeline.java#l160 by ti mohlo pomoci. Ale zrovna tady ta konkretni implementace spis zamlzi, je tam dost detailu, od kterych te interface odstini.

Mysteriozni Zeli

Re:Monády v Javě
« Odpověď #11 kdy: 09. 11. 2016, 22:44:52 »
To mi porad nepomohlo. Ano vsiml jsem si generik. Ale generIka ti nijak nepomuzou aby jsi zavolal obecne metodu x nad instanci tridy y.

Mysteriozni Z.

Re:Monády v Javě
« Odpověď #12 kdy: 09. 11. 2016, 22:49:27 »
Ok takze ptam se dal. Mam:

Kód: [Vybrat]
@Override
    public final Stream<P_OUT> filter(Predicate<? super P_OUT> predicate) {
        Objects.requireNonNull(predicate);
        return new StatelessOp<P_OUT, P_OUT>(this, StreamShape.REFERENCE,
                                     StreamOpFlag.NOT_SIZED) {
            @Override
            Sink<P_OUT> opWrapSink(int flags, Sink<P_OUT> sink) {
                return new Sink.ChainedReference<P_OUT, P_OUT>(sink) {
                    @Override
                    public void begin(long size) {
                        downstream.begin(-1);
                    }

                    @Override
                    public void accept(P_OUT u) {
                        if (predicate.test(u))
                            downstream.accept(u);
                    }
                };
            }
        };
    }

Porad tam nevidim odpoved na co se ptam, jsem u:

Kód: [Vybrat]
predicate.test(u);

Mysteriozni Z.

Re:Monády v Javě
« Odpověď #13 kdy: 09. 11. 2016, 22:57:24 »
Rozumim teto variante:

Kód: [Vybrat]
Files.walk(Paths.get("C:\\"))
            .map(Path::toFile)
            .filter(file -> file.isFile())
            .forEach(file -> System.out.println(file.getAbsolutePath()));

Protoze jsem to JA, kdo tam napise, co se ma konkretne zavolat nad file. Ale ne teto variante, paklize tam vnitrne neni pouzita reflexe nebo File::isFile neni tridni metoda:

Files.walk(Paths.get("C:\\"))
            .map(Path::toFile)
            .filter(File::isFile())
            .forEach(file -> System.out.println(file.getAbsolutePath()));

Mysteriozni Z.

Re:Monády v Javě
« Odpověď #14 kdy: 09. 11. 2016, 22:59:03 »
Kdo to vysvetli je borec.